前言
跨域相关
这是一个 经常会碰到的问题
然后 常见的解决方式 也大概就是几种, 各有各的问题
这里仅仅是 从理论上 来探讨这个问题
主流的解决方式 是通过代理, 将不同域 合并到同一个域
测试用例
测试用例如下, 这里仅仅是一个简单的数据展示
获取对方 “/config.json” 的接口的数据, 然后展示出来
无跨域的情况下直接请求 “/config.json”, 这种情况下 正常展示业务数据
跨域的情况 配置为 其他服务器的 “/config.json” 的请求[这里为 http://172.27.181.126:10080/config.json], 这时候会碰到 跨域的问题
<template>
<div id="text" >
<button @click="handleClick" > click </button>
{{text}}
</div>
</template>
<script>
import $ from 'jquery'
export default {
name: "HelloWord",
components: {
},
data() {
return {
text: "text"
}
},
methods: {
mounted() {
},
handleClick() {
var _this = this
console.log("xx")
$.get("/config.json", function(data) {
console.log(data)
_this.text = data
})
}
}
}
</script>
<style>
</style>
在无跨域的问题下面, 初始化状态如下
https://img-blog.csdnimg.cn/f3af7131cd25421b9cb1e409cd85ab6b.png" width="1200" />
点击按钮之后, 能够正常拿到数据, 并且 正常展示
https://img-blog.csdnimg.cn/4ce455d15da44f82b1cd68c8e62427dd.png" width="1014" />
构造跨域的情况, 更新 url 为 “http://172.27.181.126:10080/config.json”
发送请求之后 报错如下, 这是一个 典型的跨域异常
https://img-blog.csdnimg.cn/20fba480f8434232bc4240ba7e59e865.png" width="1200" />
访问的这两个不同服务, 不同之处在于 一个里面 from 的值是 node, 一个 from 的值是 nginx
本域的服务如下
https://img-blog.csdnimg.cn/6060e3df9a42468aa14218f47f1829e0.png" width="431" />
第三方域的服务如下
https://img-blog.csdnimg.cn/7550ea8825d34da59f9d603eebd7da93.png" width="546" />
浏览器默认的安全策略配置
Chrome 的启动命令增加如下参数 “--disable-web-security --user-data-dir=D:\ChromeDevData”
关闭 浏览器的web安全策略
https://img-blog.csdnimg.cn/aaff7ad5a87044b1ac12d15925f0e062.png" width="390" />
然后 实际运行, 效果如下
可以看到 跨域的异常被跳过了
https://img-blog.csdnimg.cn/32c1d782c4904b5e965c2eb943b429f8.png" width="1034" />
对方服务器增加允许跨域的相关响应头配置
这个相当于是 客户端这边和对方服务器沟通之后, 对方服务器告诉客户端这边, 需要允许跨域, 客户端这边才能正常的访问对方服务器的服务
服务器这边增加 允许跨域 的相关配置, 配置信息如下
add_header Access-Control-Allow-Origin "*";
add_header Access-Control-Allow-Methods "POST,GET,OPTIONS,DELETE";
add_header Access-Control-Allow-Credentials "true";
https://img-blog.csdnimg.cn/8693fe4d0e6541a7bd936f4bfe6b4861.png" width="610" />
然后 服务器相应数据如下
https://img-blog.csdnimg.cn/99304d62c76e405389c50cd8c5df1da8.png" width="611" />
然后 我们看一下 页面的情况, 可以看到 跨域问题 也没有了
https://img-blog.csdnimg.cn/bf1b7c55040c456a9cd3c946ba91be86.png" width="879" />
基于 jsonp 来解决跨域问题
当然 这个同样需要服务器配合, 或者 增加代理服务器 专门转义这块的 wrap
客户端这边处理如下, 直接基于 jquery 中提供的 $.ajax 中相关配置来实现这个处理
主要是 封装 script 标签, 封装 jsoncallback 函数, script 标签主要是用于获取 对方服务器的信息, 拿到的是 jsoncallbck($response)
主要依据的是 script 标签, 没有 跨域策略的限制
然后 jsoncallback 是 jquery 这边自己根据 success 来进行封装的
https://img-blog.csdnimg.cn/abb835e4cd20454683bf1544350df90f.png" width="556" />
需要调整服务器这边的处理, wrap 一下, 封装 jsonpcallback 的函数封装格式
使其满足 javascript 的语法格式, 然后 客户端拿到这段内容之后, 将其执行, 进而实现 业务处理
https://img-blog.csdnimg.cn/3852fc25568a4802b23512a2fcc9397c.png" width="494" />
基于代理服务, 统一访问的域
比如我们这里有 node 服务作为本地服务, nginx 作为对方服务
从部署到生产环境的角度来看
那么 可以在 nginx 上面增加配置, 组合 node 服务 和 目标静态资源服务, 比如这里 “location /” 是对应于静态资源服务, ”location /HelloWorld” 对应于 node 服务
然后 这时候通过 nginx 来访问 node 的页面, 然后 页面 $ajax 这边访问的 url 更新为 “/config.json”, 这样就不会存在 跨域的问题了
https://img-blog.csdnimg.cn/04b1929121814a2a9210b3d362b78922.png" width="652" />
从另一个角度, 从开发的角度来看, 在 vue 的开发服务器上面配置 相关代理
vue.config.js 中 devServer 的代理配置如下, “/config.json” 代理到 目标服务器上面去
https://img-blog.csdnimg.cn/f9d97269cb4044aeb68f44855f5624fe.png" width="526" />
业务测使用, 直接请求本域的数据服务 即可
https://img-blog.csdnimg.cn/6b78fcf4f94149e39bc92f2af19375ac.png" width="462" />
最终页面效果如下, 从 from 可以判断出 获取的是 对方服务器的数据
这里存在的一个冲突是, 如果 node 上面本身也有 “/config.json” 的服务, 会优先选择 node 上面的 “/config.json”
https://img-blog.csdnimg.cn/b736afcff4fe496d89ca3775e47d2273.png" width="868" />
chrome 访问对方服务器的时候可能会出现 net::ERR_UNSAFE_PORT
这个是 chrome 这边的一些 安全策略的控制, 发现访问的端口是 某敏感端口, 直接 block 掉请求
浏览器 网络这边的情况如下
https://img-blog.csdnimg.cn/13356abeb0b14cea8ef7ad73486ef244.png" width="1200" />
然后 console 这边报错如下, 错误信息为 ERR_UNSAFE_PORT
https://img-blog.csdnimg.cn/21a7b82e254b4b02a27eb4fcae289921.png" width="1200" />
这种情况下, 在 chrome 的启动快捷方式中增加如下 参数即可 “ --explicitly-allowed-ports=10080”
https://img-blog.csdnimg.cn/aa1a4cce68b54f688e835b9705d83bbc.png" width="407" />
完