协议 + 端口 + 端口 三者必须相同。(同源策略)
如果缺少了同源策略,浏览器很容易受到 XSS、CSRF 等攻击
、
、
跨域并不是请求发送不出去,请求能发送产前样,服务端能收到请求并正常返回结果,只不过结果被浏览器拦截了
前者是发送跨域请求给到后端,并不去接收服务器返回的信息
后者是发送跨域请求给到后端,并接收服务器返回的信息
JSONP 的原理是利用标签的跨域特性,可以不受限制地从其他域中加载资源
function jsonp(options) {
var script = document.createElement('script');
// 参数处理
var params = '';
for (var attr in options.data) {
params += '&' + attr + '=' + options.data[attr];
}
// 设置回调函数
var successCallback = `successCallback`;
window[successCallback] = options.success;
script.src = options.url + '?callback=' + successCallback + params;
document.body.appendChild(script);
}
代码解释:但请求成功后,前端得执行回调函数,但 script 脚本是执行不到 success() 方法的。这是因为 success() 方法 并不是 全局函数
所以需要将 success() 方法 改成全局函数
var successCallback = `successCallback`;
window[successCallback] = options.success;
并在请求参数的基础上,需要添加 callback
参数,值对应需要回调的函数名
script.src = options.url + '?callback=' + successCallback + params;
使用:
var btn = document.getElementById('btn');
btn.addEventListener('click', function() {
jsonp({
url: 'http://localhost:3001/getUserInfo',
data: { name: '浩浩' },
success: function(data) {
alert('UserInfo:' + JSON.stringify(data));
}
})
});
JSONP 优缺点
后端解决跨域问题,就是在服务器端给响应添加头信息
Name | Required | Comments |
---|---|---|
Access-Control-Allow-Origin | 必填 | 允许请求的域 |
Access-Control-Allow-Methods | 必填 | 允许请求的方法 |
Access-Control-Allow-Headers | 可选 | 预检请求后,告知发送请求需要有的头部 |
Access-Control-Allow-Credentials | 可选 | 表示是否允许发送cookie,默认false; |
Access-Control-Max-Age | 可选 | 本次预检的有效期,单位:秒; |
const Koa = require('koa')
const app = new Koa()
app.all("*", (req, res, next) => {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "content-type");
// 关键点
next()
})
const Koa = require('koa')
const app = new Koa()
app.all("*", (req, res, next) => {
// 设置域名跨域
res.header("Access-Control-Allow-Origin", "http://127.0.0.1");
// 跨域允许的请求方式
res.header("Access-Control-Allow-Headers", "DELETE,PUT,POST,GET,OPTIONS");
// 关键点
next()
})
location /example {
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods *;
# add_header Access-Control-Allow-Methods GET,POST,OPTIONS;
}