前端跨域
跨域
为何会产生跨域?

跨域问题来源于浏览器同源策略的限制问题导致的。
浏览器为何要设置同源策略
正是因为浏览器要出于安全考虑。如果缺少了同源策略,浏览器很容易受到XSS和CSRF等攻击。(XSS与CSRF可以单独成为一个额外的知识点) 此时会导致一个域名下网页的操作就可以直接拿到另一个非同域名下网页的任何信息,或者一个网页可以随意请求到不同域名服务器下的接口数据。
什么是同源策略?
同源策略是一种约定,这是浏览器核心的安全功能点之一。所谓的同源策略指的是【协议 + 域名 + 端口】三者相同,如果两个相同的域名指向同一个ip地址,也是非同源的情况。同时地址印射对应的ip两者也是非同源情况。

同源策略会存在哪些限制?
跨域地址场景图

如何解决跨域?
JSONP ✔
此处不做详细介绍,原因:
CORS与JSONP的使用目的相同,但是比JSONP更强大。
JSONP只支持 GET 请求,CORS支持所有类型的HTTP请求。JSONP的优势在于支持老式浏览器,以及可以向不支持CORS的网站请求数据。
@CrossOrigin 注解 ✔
CORS 需要服务器设置header :Access-Control-Allow-Origin。
也就是说 服务器的代码段 加入@CrossOrigin 注解
SSO报错
服务器加入注解 @Login(AuthenType.json) —单点登录+验证权限
nginx 反向代理
找到nginx的配置文件“nginx.conf”,修改一下信息
server {
listen 80; #监听80端口,可以改成其他端口
server_name localhost; # 当前服务的域名
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
proxy_pass http://localhost:81;
proxy_redirect default;
}
location /apis { #添加访问目录为/apis的代理配置
rewrite ^/apis/(.*)$ /$1 break;
proxy_pass http://localhost:82;
}
#以下配置省略
webpack-devServer-Proxy ✔

在webpack.dev.js 内配置 || vue-cli 3.0 ==> vue.config.js内配置
举例:localhost:8080/api/xxx 代理到 http://192.168.10.183:8103/api/xxx,如果用pathRewrite重写则代理到http://192.168.10.183:8103/xxx
将'/api'转为'/'
proxyTable: { '/api': {// '/api':匹配项
target: 'http://192.168.10.183:8103',// 接口的域名
// secure: false,// 如果是https接口,需要配置这个参数
changeOrigin: true,// 如果接口跨域,需要进行这个参数配置
// pathRewrite: {// 如果接口本身没有/api需要通过pathRewrite来重写了地址
// '^/api': '/'
// }
}
}
实际使用中 举个例子
// 引入axios
import axios from 'axios';
export function getProductTree() {
// 用axios.get()请求资源
return axios.get('/api/pageblock/getProductCategoryTree')
}
/---------------------------或者----------------------------/
import request from '@/utils/request';
export function getList(params) {
return request({
url: '/getmap',
method: 'post',
data:params
})
}
Chrome 插件 Access-Control-Allow-Origin ✔
Allow-Control-Allow-Origin: *
去应用市场下载此插件

打开插件 配置你需要跨域的地址点击【+】

在前后端联调时,不通过后端设置,如何解决跨域问题?PS: 不推荐 特别不推荐
关闭浏览器跨域策略。
通过之前分析整个跨域模式是由前台浏览器的所作所为造成的。为了安全,浏览器对跨域请求做了一系列的验证。那是否可以想想, 通过手动关闭浏览器跨域策略是不是可以解决根本性的问题。
Mac 创建一个chrome.sh文件
#!/bin/bash
#!/bin/sh
open -a "Google Chrome" --args --disable-web-security --user-data-dir
exit 0
复制代码
通过终端运行:
sh 加上chrome.sh文件地址
复制代码
注意: 在运行终端命令的时候,先检查是否已经启动过chrome,如果启动过需要手动关闭整个chrome的进程。
成功结果:
输入URL地址之后。所有的跨域问题会一并解决。
原理
虽然浏览器的跨域策略已经被关闭了。不存在任何浏览发送的跨域行为, 其内部原理正是因为浏览器会对简单的跨域请求做了拦截和复杂的跨域请求做了发送预检。
用node export 原生API 解决跨域 ✔
app.use('/api', (req, res) => {
const reqHttp = http.request({
host: '127.0.0.1',
path: '/getUser',
port: '4000',
method: req.method,
headers: req.headers
}, (resHttp) => {
let body = ''
resHttp.on('data', (chunk) => {
console.log(chunk.toString())
body += chunk
});
resHttp.on('end', () => {
res.end(body)
});
})
reqHttp.end()
});
以上代码本质上是模拟了代理劫持的方式,同时当拦截到url开头以/api起始的请求之后,通过node原生http模块的request方法向对应的后台发送请求,同时把浏览器请求过来的一些请求体,请求头等数据一并传给server端。通过http模块监听的结束方法最后把数据再返回到client浏览器端。这样形成了二次转方式解决跨域问题。整体就是利用了服务端向服务发送请求不会有跨域策略的限制,就是所谓的同源策略。因为浏览器会做options等预检的检测,而服务端并不会。
原理解析
1.同源策略
线上环境 --for 同源策略
- 页面访问接口 都是通过 hostName + port + ‘具体接口’ //bad
- 在运维层 封装 hostName+port+ ‘具体接口’ == 域名 + ‘具体接口’ //good
【例子】
https://192.168.2.188+8888/projectServer/getUserInfo
转换
https://incsit.huaxiafinance.com/projectServer/getUserInfo
2.反向代理
生产环境 —for 反向代理
- 页面访问接口 都是通过 /api/ + ‘具体接口’ //---->/api/ 通配符 前端替换 /api/ 到目标地址
- nginx 替换 /api/ 到目标地址
【例子】
/projectServer/getUserInfo
转换
https://incsit.huaxiafinance.com/projectServer/getUserInfo
3.设置跨域请求头
- 如果设置 Access-Control-Allow-Origin:*,则允许所有域名的脚本访问该资源。
- Access-Control-Allow-Origin:http://www.phpddt.com.com,允许特定的域名访问。
- 此处类似后端代码服务入口设置 @CrossOrigin
总结
线上环境 使用同源策略
生产环境 使用反向代理
注意
线上环境,预生产环境,切记去掉@CrossOrigin
参考链接
nginx反向代理-解决前端跨域问题
前端跨域策略实践
跨域多方位解决方案
vue axios
利用Access-Control-Allow-Origin响应头解决跨域请求原理