如何实现跨域请求

80 阅读2分钟

同一个域:协议+域名(主机)+端口号相同,才叫同一个域名 如果有一个不同,就叫跨域了 如何在不同的域间发送请求

思路1:JSONP(JSON with Padding。即JSON数据被包裹了一层) 假如以下文件访问的路径为localhost:8080/static/index.html

<script>
    window.callback1=function(data){
        console.log(data)
    } 
</script>
<script src="http://localhost:8081/static/index.js"></script>
//在服务器端的index.js代码里会调用定义的全局函数 callback1
callback1({name:'name'})

html5里的script标签默认的type属性是text/javascirpt。因为定义了这个类型。请求的内容会被浏览器执行。 JSONP有个比较大的缺点,只支持GET,不支持POST。就诞生了CORS.浏览器在发送请求时,会在请求头里添加origin.origin:协议+主机+端口。表明这是一个跨域请求。服务端如果允许跨域,则会加上响应头 Access-Control-Allow-Origin:协议+主机+端口。

f6a8ba62abafa664f51fc1c406efec8.png

浏览器通过这个头部属性,就能知道能否进行跨域请求了

<script>
    fetch("http://localhost:1989")
    .then(res=>res.json())
    .then(data=>{
        console.log(data)
    })
</script>
//以下是服务器端
const express=require("express")
const cors=require('cors')
const app=express()
app.use(
    cors({ //cors是个中间件
      origin:"*"
    })
)
app.get('/',(req,res)=>{
    res.json({name:"hello,word"})
})
app.listen(1989)

如果在请求时,恶意地添加了delete,
fetch("http://localhost:1989",{method:'DELETE'}) 这时netwokrk这边显示的请求方法是OPTIONS.这是浏览器的策略。当用户想修改服务器端的数据时,如PUT,PATCH,DELETE方法等,浏览器会自动发送一个预检请求,即查看服务器是否支持当前的跨域请求,预检请求没有具本设定哪个方法,而是使用OPTIONS. 此时response的header里也会显示相关的方法

Access-Control-Allow-Methods:GET,HEAD,PUT,PATCH,POST,DELETE  //这是默认的响应头方法

只有允许,才能正常请求。因此服务端那边正常都会设置好允许使用的方法。 如服务器端不允许使用DELETE,但浏览器使用了,则会抛出跨域

app.use(
    cors({ //cors是个中间件
      origin:"*",
      methods:['GET','POST']
    })
)
//这里响应头里会设置
Access-Control-Allow-MethodsGET,POST

CORS的核心简单来说就是设置头部Access-Control-Allow-Origin 另一个解决跨域的问题是利用反向代理