跨域问题:由于浏览器的 同源策略 限制,当一个请求url的协议、域名、端口号三者之间有任意一个与当前的url不同即为跨域。
同源策略是一种约定,它是浏览器中最核心也最基本的安全功能。同源策略会阻止一个域的 Javascript 脚本和另一个域的内容进行交互。同源(即指在同一个域)就是两个页面具有相同的协议(protocol)、主机(host) 和 端口号 (port)。
博客系统项目中出现跨域问题 是由于这是前后端分离项目,前端访问路径的端口和后端访问路径的端口不一致,因此出现了跨域问题,解决方案是对前端做跨域配置。
常见解决跨域问题的方式:
1. 使用 jsonp 来实现跨域请求:(jsonp函数封装)JSONP 方式实现跨域请求数据_jsonp跨域请求实现示例_TKOP_的博客-CSDN博客
原理:通过动态构建 script 标签来实现跨域请求, 因为浏览器对 script 标签的引入没有跨域的访问限制。
过程:通过在请求的url后指定一个回调函数,然后服务器在返回数据的时候,构建一个json数据的包装,这个包装就是回调函数,然后返回给前端。
前端接受到数据后,因为请求的是脚本文件,所以会直接执行,这样之前定义好的回调函数就可以被调用,从而实现了跨域请求的处理。
<body>
<h2>A服务器的页面</h2>
<button id="btn">向B发送jsonp请求</button>
<script type="text/javascript">
var btn = document.getElementById('btn');
function jsonp(options) {
// 处理其他参数的拼接
var params = '';
for (var k in options.data) {
params += '&' + k + '=' + options.data[k];
}
// 响应处理函数
var fnName = 'myJsonp' + Math.random().toString().replace('.', '');
window[fnName] = options.success;
// 请求完整地址
var url = options.url + '?callback=' + fnName + params;
// 创建script标签
var script = document.createElement('script');
// 设置script标签的src属性
script.src = url;
// 将script标签追加到页面中
document.body.appendChild(script);
// 在script标签追加完成请求发送后将其删除
script.onload = function() {
document.body.removeChild(script);
window[fnName] = null;
}
}
btn.onclick = function() {
jsonp({
// 地址
url: 'http://localhost:3001/jsonp3',
// 其他请求参数
data: {
name: 'tkop',
age: 18
},
// 响应处理函数
success: function(data) {
console.log(data);
}
})
}
</script>
</body>
2. 使用 CORS 的方式:
跨越资源共享CORS,它运行浏览器向跨源服务器发出 XMLHttpRequest 或 Fetch 请求。目前浏览器都支持这个功能,只需要服务器设置 Access-Control-Allow-Origin 就可以开启CORS。
app.use(async (ctx, next) => {
ctx.set('Access-Control-Allow-Origin', '*')
ctx.set('Access-Control-Allow-Headers','Content-Type,Content-Length,Authorization,Accept,X-Requested-With')
ctx.set('Access-Control-Allow-Methods', 'PUT,POST,GET,DELETE,OPTIONS')
if (ctx.method === 'OPTIONS') {
ctx.body = 200;
} else {
await next()
}
});
3. 使用 Node
同源策略 是浏览器需要遵循的标准,如果是服务器 向 服务器 请求 就无需遵循同源策略。所以可以使用Node中间件代码(两次跨域):
接受客户端请求 → 将请求转发给服务器 → 拿到服务器响应数据 → 将响应转发给客户端
4. 使用代理服务器
有跨域的请求操作时发送请求给后端,让后端代为请求,然后最后将获取的结果返回。因为服务器没有跨域接口限制。