跨域的解决方案

457 阅读2分钟

一、什么是跨域

跨域,是由浏览器的同源策略造成的,目的是让浏览器不能执行其他网站的脚本。所谓的同源是指“协议+域名+端口号”都要一致。

二、跨域的解决办法

这里我们用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>

没错,报错了

跨域.PNG

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/testapi 會被空字串取代,而保留 test,从而得到了数据。
结果

跨域001.PNG

以上就是我对这三种跨域的具体实现方式给出的答案,希望能够帮助到你,要是觉得有不足的地方,欢迎留言我们交流交流,互相进步,谢谢。