跨域问题是在Web开发中常遇到的问题,尤其是在前后端分离的架构中更为常见。本文将从跨域的定义和原因入手,介绍几种常见的跨域解决方案,并结合相关代码实现。
一、什么是跨域?
跨域是指在浏览器中,当一个WEB程序(比如一个JavaScript脚本)请求另一个源的资源时,如果这个资源所在的源和当前应用程序的源不同,那么就会产生跨域问题。
首先一个url是由:协议、域名、端口 三部分组成。(一般端口默认80)
当一个请求url的协议、域名、端口三者之间的任意一个与当前页面url不同即为跨域。
二、跨域原因
跨域问题的产生,是因为浏览器的同源策略(Same-Origin Policy)所导致的。同源策略要求,一个源下的脚本只能访问同源的文档和数据,而不能访问其他源的文档和数据。比如,www.juejin.cn 和 www.juejin.cn 就不属于同源,他们的协议不一样。
三、解决方式以及相关代码
1、JSONP
原理:script标签不受浏览器同源策略影响,不单单是script,带src的都不受浏览器同源策略影响。
基于这个特性,我们把要请求的资源放在script标签的src属性中,使用callback拿到所需的数据。但是这个方法只支持get请求
<script src="http://127.0.0.1:1111/jsonp?callback=handleCallback"/>
<script>
function handleCallback(res) {
console.log(JSON.stringify(res));
}
</script>
//服务端
router.get('/jsonp', async ctx => {
var data = { 'data': 'post data' };
ctx.response.body = ctx.query.callback + '(' + JSON.stringify(data) + ');';
})
2、跨域资源共享(CORS)
只要在服务端设置Access-Control-Allow-Origin就可以实现跨域请求。CORS是目前主流的跨域解决方案。
//前端
fetch('http://127.0.0.1').then(res=>{
console.log(res)
})
//服务端
var http = require('http');
var server = http.createServer();
server.on('request', function(req, res) {
res.writeHead(200, {
'Access-Control-Allow-Credentials': 'true', // 后端允许发送Cookie
'Access-Control-Allow-Origin': 'https://mfaying.github.io', // 允许访问的域(协议+域名+端口)
'Set-Cookie': 'key=1;Path=/;Domain=mfaying.github.io;HttpOnly' // HttpOnly:脚本无法读取cookie
});
res.write(JSON.stringify(req.method));
res.end();
});
server.listen('8080');
console.log('Server is running at port 8080...');
3、nginx反向代理
原理:同源策略是浏览器的行为,服务端不受影响,所以让同源服务端去转发接口获取资源。
//nginx配置
#proxy服务器
server {
listen 81;
server_name www.test1.com;
location / {
proxy_pass http://www.test2.com:8080; #反向代理
proxy_cookie_test www.test2.com www.test1.com; #修改cookie里域名
index index.html index.htm;
add_header Access-Control-Allow-Origin http://www.test1.com; #当前端只跨域不带cookie时,可为*
add_header Access-Control-Allow-Credentials true;
}
}
总结:
另外我们还可以通过 window.name、location.hash等方法实现跨域请求。
跨域问题是当前前端开发中常见的问题,CORS是一种常用的解决跨域问题的机制,它基于HTTP头部,通过在服务器端设置响应头部字段来允许客户端访问来自其他域的请求。在实际开发中,开发者可以根据具体情况选择不同的跨域解决方案来解决跨域问题。