在使用Vue搭建的一个后端管理系统中,我使用axios请求本地的Node环境下的接口,可是请求失败,而后我错误信息是:
大概意思就是不能访问http://localhost:8080
个人Vue项目端口是http://localhost:8081
,Node服务端运行在http://localhost:8080
端口上,也就是说由于请求端口和响应端口不一致,因此请求失败。
我也在网上查看了一些关于跨域出现的缘由及解决的方法,并记录下来。html
跨域一句话的理解就是:服务端和请求端的地址不同。
Ajax 的便利性你们都清楚,能够在不向服务器提交完整的页面的状况下,实现局部更新页面。可是浏览器处于对安全方面的考虑,不容许跨域调用其余页面的对象。
其实这个也不能怪浏览器,假设谁均可以随随便便向你发送请求,那样有很大的安全隐患。
根据浏览器的同源策略, 只有当协议,域名,端口相同的时候才算是同源, 反之则均视为是一个跨域的请求.
也就是说我刚刚的Vue端口是8081
,服务端端口是8080
,端口不同,由于同源策略的存在 ,全部个人请求会失败。前端
一个问题,当找到了缘由,这个问题就解决了一半了。
下面就先介绍三种跨全域的方法:node
应该是最多见解决跨域的方法了,
他为何能解决跨域呢,是由于Web 页面上调用 js 文件不受浏览器同源策略的影响,因此经过 Script 便签能够进行跨域的请求:jquery
个人前端是index.html
,后端是server.js
后端逻辑:ios
//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
运行
前端:ajax
//index.html <body> <script> function jsonpCallback(data) { console.log('得到 X 数据:' + data.x); } </script> <script src="http://localhost:3000?callback=jsonpCallback"></script> </body>
以后打开index.html;就能够在控制台看到返回的数据了:npm
至此,经过 JSONP 跨域获取数据已经成功了,jsonp这种方法跨域,他的兼容性很好,能够在古老的浏览器中国使用,由于这种方法是利用了<script>
标签的特殊性,全部只支持GET请求。json
CORS 是一个 W3C 标准,全称是"跨域资源共享"(Cross-origin resource sharing)它容许浏览器向跨源服务器,发出 XMLHttpRequest 请求,从而克服了 ajax 只能同源使用的限制。axios
CORS 须要浏览器和服务器同时支持才能够生效,对于开发者来讲,CORS 通讯与同源的 ajax 通讯没有差异,代码彻底同样。浏览器一旦发现 ajax 请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感受。segmentfault
所以,实现 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的网站请求数据。
服务器代理,顾名思义,当你须要有跨域的请求操做时发送请求给后端,让后端帮你代为请求,而后最后将获取的结果发送给你。
假设有这样的一个场景,你的页面须要获取 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>
这样就成功了
经常使用的跨域方式基本就是这三种:
优势是能够兼容老浏览器,缺点是只能发送GET请求
优势简单方便,支持post请求,缺点是须要后端的配合,不支持老版浏览器。。
优势是前端正常发送ajax请求,缺点是后端会二次请求。
其余的跨域方式还有:location.hash
、window.name
、postMessage
等方式,有时间也能够了解一下。
参考资料: