在运用Vue搭建的一个后端治理体系中,我运用axios要求当地的Node环境下的接口,然则要求失利,然后我错误信息是:
也许意义就是不能接见http://localhost:8080
我的Vue项目端口是http://localhost:8081
,Node效劳端运转在http://localhost:8080
端口上,也就是说由于要求端口和相应端口不一致,所以要求失利。
我也在网上查看了一些关于跨域涌现的缘由及处理的要领,并记录下来。
为何会有跨域
跨域一句话的明白就是:效劳端和要求端的地点不一样。
什么是跨域
Ajax 的便利性人人都清晰,能够在不向效劳器提交完整的页面的情况下,完成部分更新页面。然则浏览器处于对平安方面的斟酌,不许可跨域挪用其他页面的对象。
实在这个也不能怪浏览器,假定谁都能够马马虎虎向你发送要求,那样有很大的平安隐患。
依据浏览器的同源战略, 只有当协定,域名,端口雷同的时刻才算是同源, 反之则均视为是一个跨域的要求.
也就是说我方才的Vue端口是8081
,效劳端端口是8080
,端口不一样,由于同源战略的存在 ,一切我的要求会失利。
一个题目,当找到了缘由,这个题目就处理了一半了。
怎样处理跨域
下面就先引见三种跨全域的要领:
JSONP
应该是最常见处理跨域的要领了,
他为何能处理跨域呢,是由于Web 页面上挪用 js 文件不受浏览器同源战略的影响,所以经由过程 Script 便签能够举行跨域的要求:
- 起首前端先设置好回调函数,并将其作为 url 的参数。
- 效劳端接收到要求后,经由过程该参数取得回调函数名,并将数据放在参数中将其返回
- 收到效果后由于是 script 标签,所以浏览器会当作是3剧本举行运转,从而到达跨域猎取数据的目标。
我的前端是index.html
,后端是server.js
后端逻辑:
//server.js
const url = require('url');
const http = require('http');
http.createServer((req, res)=>{
const data = {
x: 10//返回的数据
};
const callback = url.parse(req.url, true).query.callback;
res.writeHead(200);
res.end(`${callback}(${JSON.stringify(data)})`);
//实行回调函数,返回data
}).listen(3000, 'localhost');
console.log('启动效劳,监听 localhost:3000');
然后运用node server.js
运转
前端:
//index.html
<body>
<script>
function jsonpCallback(data) {
console.log('取得 X 数据:' + data.x);
}
</script>
<script src="http://localhost:3000?callback=jsonpCallback"></script>
</body>
以后翻开index.html;就能够在控制台看到返回的数据了:
至此,经由过程 JSONP 跨域猎取数据已胜利了,jsonp这类要领跨域,他的兼容性很好,能够在陈旧的浏览器中国运用,由于这类要领是利用了<script>
标签的特殊性,一切只支撑GET要求。
CORS
CORS 是一个 W3C 规范,全称是”跨域资源共享”(Cross-origin resource sharing)它许可浏览器向跨源效劳器,发出 XMLHttpRequest 要求,从而克服了 ajax 只能同源运用的限定。
CORS 须要浏览器和效劳器同时支撑才能够见效,关于开发者来讲,CORS 通讯与同源的 ajax 通讯没有差异,代码完整一样。浏览器一旦发明 ajax 要求跨源,就会自动增加一些附加的头信息,偶然还会多出一次附加的要求,但用户不会有觉得。
因而,完成 CORS 通讯的关键是效劳器。只需效劳器完成了 CORS 接口,就能够跨源通讯。
前端:
<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
<script>
$.ajax({
url:"http://127.0.0.1:3000",
success:function(res){
var res = JSON.parse(res);
$('body').text(res.data);
console.log(res.data);
}
});
</script>
此次前端启动须要运用node-server
来启动,运用npm install node-server
下载,然后当前目录下运用node-server
就能够了
后端:
const http = require('http');
http.createServer((req, res)=>{
const data = {
'data': 'Hello world'//返回的数据
};
res.writeHead(200, {'Access-Control-Allow-Origin': 'http://127.0.0.1:8080'});
//设置的头部信息须要和前端要求的地点一致
res.end(JSON.stringify(data));
//返回data
}).listen(3000, '127.0.0.1');
console.log('启动效劳,监听 127.0.0.1:3000');
运用敕令node server.js
启动;
CORS与JSONP的运用目标雷同,然则比JSONP更壮大。
JSONP只支撑GET要求,CORS支撑一切范例的HTTP要求。JSONP的上风在于支撑老式浏览器,以及能够向不支撑CORS的网站要求数据。
Server Proxy
效劳器代办,望文生义,当你须要有跨域的要求操纵时发送要求给后端,让后端帮你代为要求,然后末了将猎取的效果发送给你。
假定有如许的一个场景,你的页面须要猎取 CNode:Node.js专业中文社区 论坛上一些数据,如经由过程 https://cnodejs.org/api/v1/topics,当时由于差别域,所以你能够将要求后端,让其对该要求代为转发。
后端代码以下:
const url = require('url');
const http = require('http');
const https = require('https');
http.createServer((req, res)=>{
const path = url.parse(req.url).path.slice(1);
//查对要求路由是不是一致
if(path === 'topics'){
https.get('https://cnodejs.org/api/v1/topics', (resp)=>{
//https代发要求
let data='';
resp.on('data', chunk=>{
data+= chunk
});
resp.on('end', ()=>{
res.writeHead(
200,
{'Content-Type': 'application/json; charset=utf-8'}
);
res.end(data);
//返回数据
})
})
}
}).listen(3000, '127.0.0.1');
console.log('启动效劳,监听 127.0.0.1:3000');
前端代码:
<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
<script>
$.ajax({
url:"https://cnodejs.org/api/v1/topics",
success:function(res){
$('body').text(JSON.stringify(res));
console.log(res);
}
});
</script>
如许就胜利了
总结
经常使用的跨域体式格局基础就是这三种:
- JSONP
长处是能够兼容老浏览器,瑕玷是只能发送GET要求
- CORS
长处简朴轻易,支撑post要求,瑕玷是须要后端的合营,不支撑老版浏览器。。
- Server Proxy
长处是前端一般发送ajax要求,瑕玷是后端会二次要求。
其他的跨域体式格局另有:location.hash
、window.name
、postMessage
等体式格局,偶然间也能够相识一下。
参考资料:
- 跨域资源共享 CORS 详解[阮一峰的博客]:http://www.ruanyifeng.com/blo…
- 关于跨域,你想晓得的全在这里:https://zhuanlan.zhihu.com/p/…
- 不要再问我跨域的题目了[sf]:https://segmentfault.com/a/11…
- 关于跨域,以及跨域的几种体式格局[cnblog]:https://www.cnblogs.com/chens…
- 浏览器的同源战略[MDN]:https://developer.mozilla.org…