关于跨域的一些问题(易懂)
JSONP
因为ajax直接请求普通文件存在跨域问题(同源下的js发起的ajax请求是可以跨域的),甭管是啥只要是跨域请求一律都不行
****但是web页面上调用js文件时不受跨域影响(而且有src的标签都有跨域的能力)
所以在远程服务器上把数据装进js格式里,而JSON可以简洁描述复杂数据,并且被
js原生支持。所以在服务端动态生成JSON文件并把客户端需要的数据装进去
客户端调用JSON文件成功后,获得数据。这种方式很像ajax但其实不是
JSONP协议允许的是用户传递callback参数给服务端,服务端返回数据将这个callback
参数作为函数包裹住JSON数据
详见:
后端
public class JsonpServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType(“text/html”);
//获取传过来的回调函数名称
String callBackName = request.getParameter(“callBack”);
//处理业务逻辑拼接json串
String json = “{“name”:“jack”,“sex”:“man”}”;
//设置响应类型
response.setContentType(“application/json”);
//将json数据返回给请求页面
response.getWriter().write(callBackName + “(” + json + “)”);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
同源策略/SOP(Same origin policy)是一种约定,由Netscape公司1995年引入浏览器,
它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到XSS.CSFR等攻击。
所谓同源是指”协议+域名+端口”三者相同,即便两个不同的域名指向同一个ip地址,也非同源。
同源策略限制以下几种行为(就是说不同源的话):
1.) Cookie.LocalStorage 和 IndexDB 无法读取
2.) DOM 和 Js对象无法获得
3.) AJAX 请求不能发送
要注意同源的情况也是可以跨域的(同源是你协议域名端口一样啊只要一样无论你在那都能跨域)
这些都算
1.) 资源跳转: A链接.重定向.表单提交
2.) 资源嵌入: <link>.<script>.<img>.<frame>等dom标签,还有样式中background:url().@font-face()等文件外链
3.) 脚本请求: js发起的ajax请求.dom和js对象的跨域操作等
跨域解决方案 (我不同源的情况下夸不了域啊,这时我的解决方案)
1、通过jsonp跨域
用jQuery ajax写的话
$.ajax({
url: ‘http://www.domain2.com:8080/login’,
type: ‘get’, //jsonp的ajax只能get请求
dataType: ‘jsonp’, // 请求方式为jsonp
jsonpCallback: “onBack”, // 自定义回调函数名
data: {}
});
用vue写JSONP的话
this.$http.jsonp(‘http://www.domain2.com:8080/login’, {
params: {},
jsonp: ‘onBack’
}).then((res) => {
console.log(res);
})
后端
var querystring = require(‘querystring’);
var http = require(‘http’);
var server = http.createServer();
server.on(‘request’, function(req, res) {
var params = qs.parse(req.url.split(’?’)[1]);
var fn = params.callback;
// jsonp返回设置
res.writeHead(200, { 'Content-Type': 'text/javascript' });
res.write(fn + '(' + JSON.stringify(params) + ')');
res.end();
});
server.listen(‘8080’);
console.log(‘Server is running at port 8080…’);
2、document.domain + iframe跨域
3、location.hash + iframe
4、window.name + iframe跨域
5、postMessage跨域
***6、跨域资源共享(CORS)(主流方案)
普通跨域请求:只服务端设置Access-Control-Allow-Origin即可,前端无须设置。
带cookie请求:前后端都需要设置字段,另外需注意:所带cookie为跨域请求接口所在域的cookie,而非当前页。
目前,所有浏览器都支持该功能(IE8+:IE8/9需要使用XDomainRequest对象来支持CORS)),CORS也已经成为主流的跨域解决方案
原生ajax写法
var xhr = new XMLHttpRequest(); // 这就是F12里的XHR就是原生的ajax表达
// 前端设置是否带cookie
xhr.withCredentials = true;
xhr.open(‘post’, ‘http://www.domain2.com:8080/login’, true);
xhr.setRequestHeader(‘Content-Type’, ‘application/x-www-form-urlencoded’);
xhr.send(‘user=admin’);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
alert(xhr.responseText);
}
};
jQuery ajax实现跨域
$.ajax({
…
xhrFields: {
withCredentials: true // 前端设置是否带cookie
},
crossDomain: true, // 会让请求头中包含跨域的额外信息,但不会含cookie
…
});
vue实现cors跨域
vue框架在vue-resource封装的ajax组件中加入以下代码:
Vue.http.options.credentials = true
node后端
var http = require(‘http’);
var server = http.createServer();
var qs = require(‘querystring’);
server.on(‘request’, function(req, res) {
var postData = ‘’;
// 数据块接收中
req.addListener('data', function(chunk) {
postData += chunk;
});
// 数据接收完毕
req.addListener('end', function() {
postData = qs.parse(postData);
// 跨域后台设置
res.writeHead(200, {
'Access-Control-Allow-Credentials': 'true', // 后端允许发送Cookie
'Access-Control-Allow-Origin': 'http://www.domain1.com', // 允许访问的域(协议+域名+端口)
'Set-Cookie': 'l=a123456;Path=/;Domain=www.domain2.com;HttpOnly' // HttpOnly:脚本无法读取cookie
});
res.write(JSON.stringify(postData));
res.end();
});
});
server.listen(‘8080’);
console.log(‘Server is running at port 8080…’);
listen后面的就是我们所监听的那个源,只要是这个地址的就OK。不是的话好比用JSONP跨域。我只要在js标签里
做一些操作,让后台可以对接,那就没问题
7、nginx代理跨域
- Nginx配置解决iconfont跨域
浏览器跨域访问js.css.img等常规静态资源被同源策略许可,但iconfont字体文件(eot|otf|ttf|woff|svg)例外,此时可在nginx的静态资源服务器中加入以下配置。
location / {
add_header Access-Control-Allow-Origin *;
}
- Nginx反向代理接口跨域
跨域原理: 同源策略是浏览器的安全策略,不是HTTP协议的一部分。服务器端调用HTTP接口只是使用HTTP协议,
不会执行JS脚本,不需要同源策略,也就不存在跨越问题。
实现思路:通过nginx配置一个代理服务器(域名与domain1相同,端口不同)做跳板机,
反向代理访问domain2接口,并且可以顺便修改cookie中domain信息,方便当前域cookie写入,
实现跨域登录。
8、nodejs中间件代理跨域
原理和NGINX大致相同
9、WebSocket协议跨域
WebSocket protocol是HTML5一种新的协议。它实现了浏览器与服务器全双工通信,同时允许跨域通讯,
是server push技术的一种很好的实现。原生WebSocket API使用起来不太方便,我们使用Socket.io,
它很好地封装了webSocket接口,提供了更简单.灵活的接口,也对不支持webSocket的浏览器提供了向下兼容。
不建议 一般接口也不会使用WebSocket形式
SDK
最开始的时候,API的集合我们就称之为SDK,例如mac提供的API集合,就称之为mac SDK。
随着时间的演化,现在的SDK指的是以一组Api作为输入,以另外一组Api作为输出的中间件。
SDK是一些被软件工程师用于为特定的软件包、软件框架、硬件平台、操作系统等创建应用软件的开发工具的集合。
它可以简单的为某个程序设计语言提供应用程序接口API的一些文件,但也可能包括能与某种嵌入式系统通讯的复杂的硬件。
SDK还经常包括示例代码、支持性的技术注解或者其他的为基本参考资料澄清疑点的支持文档。
本文地址:https://blog.csdn.net/qq_46311036/article/details/109378994