一、什么是跨域
在前端领域中,跨域是指浏览器允许向服务器发送跨域请求,从而克服Ajax 只能使用同源的限制。
跨域本质是浏览器基于同源策略的一种安全手段。
什么是同源策略
同源策略(Sameoriginpolicy),是一种约定,它是浏览器最核心也最基本的安全功能。
所谓同源(即指在同一个域)具有以下三个相同点:
- 协议相同(protocol)
- 主机相同(host)
- 端口相同(port)
同源策略限制以下几种行为:
- Cookie、LocalStorage 和 IndexDB 无法读取
- DOM和JS对象无法获得
- AJAX 请求不能发送
反之非同源请求,也就是协议、端口、主机其中一项不相同的时候,这时候就会产生跨域。
一定要注意跨域是浏览器的限制,你用抓包工具抓取接口数据,是可以看到接口已经把数据返回回来了,只是浏览器的限制,你获取不到数据。用postman请求接口能够请求到数据。这些再次印证了跨域是浏览器的限制。
二、跨域常见的解决方案
1、jsonp 跨域
jsonp的原理就是利用
后端 node.js 的代码:
var querystring = require('querystring');
var http = require('http');
var server = http.createServer();
server.on('request', function(req, res) {
var params = querystring.parse(req.url.split('?')[1]);
var fn = params.callback;
// jsonp返回设置
res.writeHead(200, { 'Content-Type': 'text/javascript' });
res.write(fn + '(' + JSON.stringify(params) + ')');
res.end();
});
server.listen('8080');
console.log('Server is running at port 8080...');
1.1 原生的 js 实现
<script>
var script = document.createElement('script');
script.type = 'text/javascript';
// 传参一个回调函数名给后端,方便后端返回时执行这个在前端定义的回调函数
script.src = 'http://www.domain2.com:8080/login?user=admin&callback=handleCallback';
document.head.appendChild(script);
// 回调执行函数
function handleCallback(res) {
alert(JSON.stringify(res));
}
</script>
1.2 jquery Ajax 实现
$.ajax({
url: 'https://www.baidu.com/sugrec?pre=1&p=3&ie=utf-8&json=1&prod=pc&from=pc_web',
type: 'get',
dataType: 'jsonp', // 请求方式为jsonp
jsonpCallback: "handleCallback", // 自定义回调函数名
data: {}
});
1.3 vue-resource 实现
this.$http.jsonp('https://www.baidu.com/sugrec?pre=1&p=3&ie=utf-8&json=1&prod=pc&from=pc_web', {
params: {},
jsonp: 'handleCallback'
}).then((res) => {
console.log(res);
})
实例:跨域请求 https://www.baidu.com/sugrec?pre=1&p=3&ie=utf-8&json=1&prod=pc&from=pc_web
在main.js 中要安装并注册 vue-resource
import VueResource from 'vue-resource'
Vue.use(VueResource)
在.vue
文件中跨域请求。
loadData(){
this.$http.jsonp('https://www.baidu.com/sugrec?pre=1&p=3&ie=utf-8&json=1&prod=pc&from=pc_web', {
params: {},
jsonp: 'cb' //jsonp默认是callback,百度缩写成了cb,所以需要指定下
}).then((res) => {
console.log(res);
})
},
二、Proxy
代理(Proxy)也称网络代理,是一种特殊的网络服务,允许一个(一般为客户端)通过这个服务与另一个网络终端(一般为服务器)进行非直接的连接。一些网关、路由器等网络设备具备网络代理功能。一般认为代理服务有利于保障网络终端的隐私或安全,防止攻击
方案一
如果是通过vue-cli脚手架工具搭建项目,我们可以通过webpack为我们起一个本地服务器作为请求的代理对象。
通过该服务器转发请求至目标服务器,得到结果再转发给前端,但是最终发布上线时如果web应用和接口服务器不在一起仍会跨域。
在vue.config.js文件,新增以下代码:
module.exports = {
devServer: {
host: '127.0.0.1',
port: 8084,
open: true,// vue项目启动时自动打开浏览器
proxy: {
'/api': { // '/api'是代理标识,用于告诉node,url前面是/api的就是使用代理的
target: "http://xxx.xxx.xx.xx:8080", //目标地址,一般是指后台服务器地址
changeOrigin: true, //是否跨域
pathRewrite: { // pathRewrite 的作用是把实际Request Url中的'/api'用""代替
'^/api': ""
}
}
}
}
}
通过axios发送请求中,配置请求的根路径。
axios.defaults.baseURL = '/api'