如何解决跨域请求?Jsonp 跨域的原理是什么?
说起跨域请求,必须要了解浏览器的同源策略,同源策略/SOP(Same origin policy)是一种约定,由 Netscape 公司 1995年引入浏览器,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到 XSS、CSFR 等攻击。所谓同源是指"协议+域名+端口"三者相同,即便两个不同的域名指向同一个 ip 地址,也非同源。
解决跨域请求的常用方法是:
通过代理来避免,比如使用 Nginx 在后端转发请求,避免了前端出现跨域的问题。
通过 Jsonp 跨域
其它跨域解决方案
重点谈一下 Jsonp 跨域原理。浏览器的同源策略把跨域请求都禁止了,但是页面中的
JSONP 的理念就是,与服务端约定好一个回调函数名,服务端接收到请求后,将返回一段 Javascript,在这段 Javascript 代码中调用了约定好的回调函数,并且将数据作为参数进行传递。当网页接收到这段 Javascript 代码后,就会执行这个回调函数,这时数据已经成功传输到客户端了。
JSONP 的缺点是:它只支持 GET 请求,而不支持 POST 请求等其他类型的 HTTP 请求。
跨域解决方案:原生jsonp
通过动态创建script标签,通过script标签的src,向一个不同源的接口发送一个get请求
src属性发送请求时,在参数中额外携带一个callback的参数,参数值是一个在页面中预先定于好的函数名
callback属性值:预先定义的函数名,这个函数必须要在script标签之前定义
服务器接收到请求之后,获取callback的参数值
服务器将要响应的数据拼接成 函数调用格式,通过传参的方式将响应数据返回给浏览器
跨域解决方案: jQuery中的jsonp
只需要一行代码
dataType:'jsonp'
1
底层原理与原生一致,设置dataType为jsonp,jq会自动动态帮我们创建一个script标签,将url放到src属性中
细节注意点:jq使用jsonp不需要自己设置callback,jq会自动帮我们发送callback参数,参数值就是jq的success回调函数
跨域解决方案:cors技术
CORS :全称cross origin resource share (资源共享)
工作原理: 服务器 在返回响应报文的时候,在响应头中 设置一个允许的header
res.setHeader(‘Access-Control-Allow-Origin’, ‘*’)
CORS :全称cross origin resource share (资源共享)
服务器 在返回响应报文的时候,在响应头中 设置一个允许的header
2-express使用中间件cors
官网传送门:https://www.expressjs.com.cn/resources/middleware.html
xpress有一个自带的中间件cors,它的作用是自动给每一个res设置默认请求头
这样就不用我们自己每一个接口都要设置一次了
//1.下包
$ npm install cors
//2配置中间件
var cors = require('cors')
app.use(cors()
cors中间件底层原理如下
app.use((req, res, next) => {//任何请求都会进入这个use中间件
res.setHeader('Access-Control-Allow-Origin', '*')//设置响应头
next()//执行下一个中间件 })
3.3 proxy代理转发
.如果后端jsonp也不弄,cors也不弄,就给个接口地址
我们可以在本地弄个服务器, 然后用服务器请求后台服务器接口地址
.但是vuecli脚手架, 启动了一个webpack开发服务器, 它就能做代理转发(后端和后端不存在跨域问题)
.而且前端和这个服务器是同源的都是8080端口
.需要修改webpack开发服务器的配置即可
devServer: {
proxy: {
// http://c.m.163.com/nc/article/headline/T1348647853363/0-40.html
'/api': { // 请求相对路径以/api开头的, 才会走这里的配置
target: 'http://c.m.163.com', // 后台接口域名
changeOrigin: true, // 改变请求来源(欺骗后台你的请求是从http://c.m.163.com)
pathRewrite: {
'^/api': '' // 因为真实路径中并没有/api这段, 所以要去掉这段才能拼接正确地址转发请求
}
}
}
}
.axios请求的代码
axios({
url: '/api/nc/article/headline/T1348647853363/0-40.html'
})