跨域是什么
跨域的本质是浏览器基于同源策略的一种安全手段
同源策略: 是一种约定,它是浏览器的核心也是最基本的安全功能
同源:协议相同,域名相同,端口相同
跨域错误:不同源的ajax请求
注意:错误是发生在浏览器端的。请求是可以正常从浏览器发到服务器端,服务器也可以处理请求,只是返回到浏览器端时出错了
如何解决跨域错误
- JSONP
- CORS
- Proxy
JSONP
是借助于script标签发送跨域请求的技巧.本质不是ajax请求,所以没有跨域问题
原理:
- script的src属性可以请求外部js文件,这个请求不是ajax,它没有跨域问题
- 借助script标签的src请求服务器端上的接口 <script src ="http://localhost:8000/get"
- 服务器端的接口返回的JavaScript脚本,并附上要返回的数据,例如:res.end("fn(数据)")
注意:
- script标签中的src会指向一个后端接口的地址.由于script标签并不会导致跨域问题,所以这里的请求是可以正常发送和接收的
- 与我们之前理解的src指向某个具体的.js文件不同,我们只需要确保src所指向的地址返回的内容是js代码就行了,而不必要src直接指向某个.js文件
- 接口地址中返回的内容将会作为script标签的主体
CORS
CORS是一个W3C标准,全称"跨域资源共享".它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了ajax只能同源使用的限制
app.get('/get', (req, res) => {
// * 表示允许任何域名来访问
res.setHeader('Access-Control-Allow-Origin', '*')
// 允许指定源访问
// res.setHeader('Access-Control-Allow-Origin', 'http://www.xxx.com')
res.send(Date.now().toString())
})
这种方案无需客户端做出任何变化(客户端不用改代码),就当跨域问题不存在一样
服务端响应的时候添加一个 Access-Control-Allow-Origin的响应头
使用cors
1.它是一个npm包,要单独下载使用 npm包cors npm i cors
2.当做express中的中间件,注意代码应放在顶部
var cors = require('cors')
app.use(cors())
JSONP vs CORS 对比
jsonp :
- 不是ajax
- 只能支持 get 方式
- 兼容性好
cors :
- 前端不需要做额外的修改,就当跨域问题不存在
- 是ajax
- 支持各种方式的请求(post,get...)
- 浏览器的支持不好(标准浏览器都支持)
Proxy
Proxy,也称网络代理,是一种特殊的网络服务,允许一个(一般为客户端),通过这个服务与另一个网络终端(一般为服务器)进行非直接的连接.一些网关,路由器等网络设备具备网络代理功能.一般认为代理服务有利于保障网络终端的隐私安全,防止攻击
通过vue-cli脚手架工具搭建的项目,可以通过webpack为我们起一个本都服务器作为请求得代理对象
通过改服务器转发请求至目标服务器,得到结果再转发给前端,但是最终发布上线时如果web应用和接口服务器不在一起仍会跨域
在 vue.config.js文件,新增以下代码
module.exports = {
devServer: {
port: port,
open: true,// vue项目启动时自动打开浏览器
overlay: {
warnings: false,
errors: true
},
proxy: {
// 请求时的路径中以/api开头 就会走代理服务器
// 自己写路径不跨域 : http://localhost:8000/api/sys/login
// 真实的接口路径 : http://www.jd.com/api/sys/login
// http://localhost:8000/api/sys/login
// =>http://www.jd.com/api/sys/login
// =>http://www.jd.com/sys/login
'^/api': {
// target目标: 真实的接口服务器地址
target: 'http://www.jd.com'
// pathRewrite:路径重写
pathRewrite: {
'^/api': ""
}
}
}
}
}