一、为什么会出现跨域这个问题
这个问题出于浏览器的同源策略限制。
同源策略
同源策略(Sameoriginpolicy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。同源策略会阻止一个域的javascript脚本和另外一个域的内容进行交互。所谓同源(即指在同一个域)就是两个页面具有相同的协议(protocol),主机(host)和端口号(port)
二、什么是跨域呢?
一个请求的url中的协议,域名和端口号有其中一个与当前页面的url不同时,即为跨域 例子
- www.test.com 请求 www.test.com/index.html 不跨域
- www.test.com 请求 www.test.com/index.html 跨域 协议不同(http和https)
- www.test.com 请求 www.taobao.com 跨域 主域名不同(test和taobao)
- www.test.com 请求 www.mytest.test.com 跨域 子域名不同(www和mytest)
- www.test.com:8088 请求 www.test.com:8089 跨域 端口号不同(8088和8089)
三、那么跨域的解决方案是什么?
今天我们讲的是CORS和JSONP。 document.domain和window.postMessage()这两个解决跨域的方法我们就暂时不讨论。
先来讲个最简单的JSONP
- JSONP 是服务器与客户端跨源通信的常用方法。最大特点就是简单适用,兼容性好(兼容低版本IE),缺点是只支持get请求,不支持post请求。
- 核心:利用html中script标签的src属性,来请求外部链接,当请求外部链接的时候,通过在url的后面加个回调函数的名字,后端会返回这个回调函数的执行,从而实现跨域
- 例子:这是一个淘宝搜索建议的jsonp接口 淘宝商品搜索建议:suggest.taobao.com/sug?code=ut… 我们可以看到后面有个callback=cb,callback是后端规定的字段,cb是前端传的函数名(这个函数已经在前端定义好了)
<script>
function cb(res) {
console.log(res)
}
</script>
<script src="http://suggest.taobao.com/sug?code=utf-8&q=衣服&callback=cb">
</script>
通过script中的src属性,我们已经成功得到请求成功的数据,数据格式为cb('结果数据'),cb是你请求时给后端传的函数名
因此,就可以通过此方法进行跨域得到数据,缺点就是只支持get请求
CORS跨域
CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing),属于跨源 AJAX 请求的根本解决方法。 解决此跨域有三种方法
-
后端设置请求头
此方法就不介绍了,因为我也没有学习关于后端的一些语言 -
Nginx设置反向代理
在Nginx的配置文件中加上以下代码
location /api/ { #这里设置了/api,那么前端在请求时的基础路径就得加上/api
proxy_pass http://127.0.0.1:4000/;#这里指的是你的服务器运行在哪个端口
}
-
Vue或React设置代理(只能在开发环境中使用,生产环境就会失效)
这里只拿Vue来举例子 在vue.config.js这个配置文件中加上
module.exports = {
devServer: {
open: true,
proxy: {
'/api': { // 匹配所有以'/api'开头的请求路径
target: 'http://target.com', // 代理目标的基础路径
changeOrigin: true, // 支持跨域
pathRewrite: { // 重写路径: 去掉路径开头的'/api'
'^/api': ''
}
}
}
},
}~~~