什么是跨域
跨域问题本质是浏览器的一种保护机制,它的初衷是为了保证用户的安全,防止恶意网站窃取数据。 但这个保护机制也带来了新的问题,它的问题是给不同站点之间的正常调用,也带来的阻碍,那怎么解决这个问题呢?接下来我们一起来看。
跨域三种情况
在请求时,如果出现了以下情况中的任意一种,那么它就是跨域请求:
- 协议不同,如 http 和 https;
- 域名不同;
- 端口不同。
注意:跨域并不是请求发不出去,请求能发出去,服务端能收到请求并正常返回结果,只是结果被浏览器拦截了。
如何处理跨域
解决跨域的方法有很多,下面列举了三种:
- JSONP
- CORS
- Proxy
JSONP
JSONP是一种利用 <script> 标签不受同源策略限制的特性来实现跨域请求的方法。服务器返回的数据会被包裹在一个函数调用中,客户端定义该函数来处理数据。
<!-- 前端代码 -->
<script>
function handleData(data) {
// 处理返回的数据
}
</script>
<script src="http://example.com/api/data?callback=handleData"></script>
CORS
CORS是一个系统,它由一系列传输的HTTP头组成,这些HTTP头决定浏览器是否阻止前端 JavaScript 代码获取跨域请求的响应。CORS 实现起来非常方便,只需要增加一些 HTTP 头,让服务器能声明允许的访问来源。只要后端实现了 CORS,就实现了跨域。
以koa框架举例添加中间件,直接设置Access-Control-Allow-Origin响应头。
app.use(async (ctx, next)=> {
ctx.set('Access-Control-Allow-Origin', 'http://example.com'); // 允许的域
ctx.set('Access-Control-Allow-Headers', 'Content-Type');// 允许的请求头
ctx.set('Access-Control-Allow-Methods', 'PUT, POST, GET, DELETE, OPTIONS');// 允许的方法
if (ctx.method == 'OPTIONS') {
// 如果是 OPTIONS 请求,直接返回状态码 200 表示接受预检请求
ctx.body = 200;
} else {
// 如果不是 OPTIONS 请求,执行下一个中间件
await next();
}
})
Proxy
通过在同源的服务器上设置代理,实现跨域请求。前端请求同源服务器,同源服务器再将请求发送到目标服务器,然后将目标服务器的响应返回给前端。
在vue.config.js文件,新增以下代码
amodule.exports = {
devServer: {
host: '127.0.0.1',
port: 8084,
open: true,
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'