一、什么是跨域
跨域,是由浏览器的同源策略造成的,目的是让浏览器不能执行其他网站的脚本。所谓的同源是指“协议+域名+端口号”都要一致。
二、跨域的解决办法
这里我们用node来演示,先创建两个简易的node服务,分别运行在本地的90和91端口,我们要做的是在91端口的页面中发送请求获取90端口的数据。
var express = require('express')
// 90端口的服务
var app1 = express()
app1.get('/' , (req,res) => {
res.send('你好91端口')
})
app1.listen(90)
// 91端口的服务
var app2 = express()
app2.use(express.static(__dirname))
app2.listen(91)
首先如果我们像下面在90端页面中直接用fetch函数发送请求获取91端口数据,会发生什么?
<body>
<script>
fetch('http://localhost: 90/').then(function (data) {
return data.text()
}).then(function (data){
alert(data)
})
</script>
</body>
没错,报错了
1、JSONP
由于<script>标签不受同源策略的影响,我们可以在 <script>标签中的请求数据的接口链接后面拼接一个回调函数发送给服务器,服务器拿到回调函数后,会将数据拿给回调函数并返回给浏览器。浏览器就执行回调函数,数据就拿到了。
<body>
<script>
function f(data) {
console.log(data)
}
</script>
<script src='http://localhost: 90?callback=f'></script>
</body>
app1.get('/', (req,res) => {
// 拿到回调函数
var back = req.query.callback
// 数据和回调函数拼接返回给浏览器
res.send(`${back}('你好91')`)
})
2、CORS
CORS就是服务器设置响应头来实现。具体可以设置哪些响应头和怎么设置响应头,大伙可以自行查阅资料。
<body>
<h1>你好</h1>
<script>
fetch('http://localhost: 90/').then(function (data) {
return data.text()
}).then(function (data){
alert(data)
})
</script>
</body>
app1.get('/', (req,res) => {
// 设置响应头
res.header('Access-Control-Allow-Origin' , '*')
res.send(`${back}('你好91')`)
})
3、node反向代理
什么是正向代理,什么是反向代理
- 正向代理:代理端代理的是客户端,服务端认代理端不认客户端。
- 反向代理:代理端代理的服务端,客户端认代理端不认服务端。
正向代理好理解,反向代理我们举一个例子。比如你打电话给10086寻求服务,'你'是客户端,10086就是代理端,10086代理后面的人工客服(服务端)你又不在意是哪个客服给进行服务,你只知道打10086能得到服务就对了。
这边我们使用 express+express-http-proxy来实现node反向代理解决跨域问题 github地址
var express = require('express')
var proxy = require('express-http-proxy');
var app1 = express()
app1.get('/test' , (req , res) => {
res.send('你好91端口')
})
app1.listen(90)
var app2 = express()
app2.use(express.static(__dirname))
app2.listen(91)
app2.use('/api',proxy('http://localhost:90'))
<body>
<script type="text/javascript">
fetch('http://localhost:91/api/test').then(function (data) {
return data.text()
}).then(function (data) {
console.log(data)
})
</script>
</body>
我们用 fetch 发送一个请求到 http://localhost:91/api/test经过 proxy 后实际会将请求发送到 http://localhost:90/test,api 會被空字串取代,而保留 test,从而得到了数据。
结果
以上就是我对这三种跨域的具体实现方式给出的答案,希望能够帮助到你,要是觉得有不足的地方,欢迎留言我们交流交流,互相进步,谢谢。