何为跨域问题?
cors origin,浏览器安全策略,禁止一个域名下的网页中js访问其他域名下的服务
跨域还包括跨端口,款协议(https域名访问http),二级域名不同不会跨域问题
有那些处理技术
cors jsonp nginx代理 nodejs代理 前端devServer 等
cors Allow-Origin
服务端接口返回时增加 “Access-Control-Allow-Origin” = “允许的域(*为所有)” 的头,表示允许该域名下页面跨域访问
加了这个head还不能? 可能原因1:浏览器会先发送预检请求(option 方法,然后才会发送post等方法),需要同样服务端在option方法下增加该头部
除了Allow-Origin 外服务端还可以限制 Allow-Credentials,Allow-Methods等,建议服务端直接用web框架处理(gin cors: https://github.com/gin-contrib/cors )
jsonp
利用前端 script link等标签无同源限制
前端创建 script src=Url 请求服务端,服务端返回时增加头部 Content-Type=application/javascript,前端收到返回值时将作为js执行 (回调)
url格式为 url?callback={$jsFuncName}
eg vue + golang
//vue
mounted() {
window.handleResponse = this.handleResponse; // 将回调函数定义在全局作用域
const script = document.createElement('script');
script.src = 'http://localhost:8937/jsonpTest?callback=handleResponse';
document.head.appendChild(script);
},
methods: {
handleResponse(response) {
console.log(response)
// {a: 1, b: 'xxx'} 获取到了返回结构体
},
},
//go gin
route.GET("jsonpTest", func(ctx *gin.Context) {
data := gin.H{"a": 1, "b": "xxx"}
// 以下等同于 ctx.JSONP(200, data)
tmp, _ := json.Marshal(data)
callback := ctx.Query("callback")
res := fmt.Sprintf("%s(%s)", callback, tmp)
ctx.Data(200, "application/javascript", []byte(res))
})
其它
// vue devServer(仅开发环境) vue.config.js文件
module.exports = {
proxy: {
// 表示站内以path1开头的路径代理到https://targetUrl
'^/path1': {
target: 'https://targetUrl',
ws: true,
changeOrigin: true,
onProxyReq: function(proxyReq, req, res, options) {
if (req.body) {
const bodyData = JSON.stringify(req.body)
proxyReq.setHeader('Content-Type', 'application/json')
proxyReq.setHeader('Content-Length', Buffer.byteLength(bodyData))
proxyReq.write(bodyData)
}
}
},
'^/path2': ...
}
}