什么是跨域
跨域指浏览器不允许当前页面的所在的源去请求另一个源的数据。
源指协议,端口,域名。只要这3个中有一个不同就是跨域。这里列举一个经典的例子:
#协议跨域
http://a.baidu.com访问https://a.baidu.com;
#端口跨域
http://a.baidu.com:8080访问http://a.baidu.com:80;
#域名跨域
http://a.baidu.com访问http://b.baidu.com;
现在很多公司都是采用前后端分离的方式开发。那么会出现经常和跨域打交道。
我这里整理日常开发中解决跨域的几种方案。
我们前端使用的是 Vue,后端使用的是 NodeJs。
解决方案
proxyTable
这里 vue 脚手架生成的标准项目为准。一般在项目 config 目录下面有个 index 文件夹。里面格式如下:
'use strict'
const path = require('path')
module.exports = {
dev: {
// Paths
assetsSubDirectory: 'static',
assetsPublicPath: '/',
proxyTable: {
'/api': {
target: 'http://localhost:7001',//后端接口地址
changeOrigin: true,//是否允许跨越
pathRewrite: {
'^/api': '/api',//重写,
}
}
},
host: '192.168.0.104',
port: 8081,
autoOpenBrowser: false,
errorOverlay: true,
notifyOnErrors: true,
poll: false,
useEslint: true,
showEslintErrorsInOverlay: false,
devtool: 'eval-source-map',
cacheBusting: true,
cssSourceMap: false,
},
}
在上面配置中,我们根据实际情况只需修改 proxyTable 配置即可。
假设我后端请求地址是 http://localhost:7001,
所有 api 的接口 url 都以 /api 开头。
所以首先需要匹配所有以 /api 开头的,然后修改 target 的地址为 http://localhost:7001。
最后修改 pathRewrite 地址。
将前缀 '^/api' 转为 '/api'。
如果本身的接口地址就有 '/api' 这种通用前缀,就可以把 pathRewrite 删掉。
注意这个方式只能在开发环境中使用。
CORS
CORS即跨域资源共享,它定义了一种浏览器和服务器交互的方式来确定是否允许跨域请求。
它是一个妥协,有更大的灵活性,
但比起简单得允许所以这些的要求来说更加安全。
但是CORS也具有一定的风险性,比如请求中只能说明来自于一个特定的域但不能验证是否可信,
而且也容易被第三方入侵。这里一般需要后端配合,开启CORS。
一般各种语言都有类似的包。比如 NodeJs的 [Koa2-cors](https://www.npmjs.com/package/koa2-cors) 。
var koa = require('koa');
//npm install --save koa2-cors
var cors = require('koa2-cors');
var app = koa();
//开启
app.use(cors());
这个方式解决的跨域问题支持开发环境和生产环境。但是有一定的安全性问题。
Nginx
当我们明白跨域的含义之后。只要解决了源的问题,那么跨域也就不存在了。
这里我们变会想到 proxy ,同时也会想到 Nginx 。
我们只需要在部署静态资源配置下面加上红框里面的配置就可以了。
同时这个方法支持开发环境和生产环境。
后端程序代理
当然上面2个方法都需要后端的配合和需要修改服务器配置。
所以还有一种方法不需要他们配合,我们自己就可以做到。
就是我们自己启一个后端程序做代理。然后把所有的请求转发到服务器。
这里要用到的 node 的一个包 [http-proxy-middleware](https://www.npmjs.com/package/http-proxy-middleware) 。
关键代码(express)如下
测试
用 vue-cli 脚手架搭建了demo,前后端分离就有跨域问题的出现。
vue-cli 搭建 demo 步骤 (传送门):https://www.cnblogs.com/wangenbo/p/8487764.html
在网上找了2个接口做测试:
CSDN:https://www.csdn.net/api/articles?type=more&category=home&shown_offset=1524276761019196&first_view=false
掘金:https://suggest-follow-api-ms.juejin.im/v1/getByTag?tag=%E5%89%8D%E7%AB%AF&src=web&t=1
安装模块 axios 进行 ajax 请求,直接请求,肯定显示跨域,无法请求。
=============== 以下为npm run dev 跨域的解决方法 ===============
脚手架 vue-cli 已经帮我们留好了接口
参考这篇文章可以知道:https://blog.csdn.net/qq_31201781/article/details/78778193
在 config 目录下的 index.js 文件,有个参数:
proxyTable:{}
所以,把参数添加成:
原来接口:
CSDN:https://www.csdn.net/api/articles?type=more&category=home&shown_offset=1524276761019196&first_view=false
掘金:https://suggest-follow-api-ms.juejin.im/v1/getByTag?tag=%E5%89%8D%E7%AB%AF&src=web&t=1
请求链接就变成这样了:
最后把数据打印出来,就可以了。
=============== 以上为npm run dev 跨域的解决方法 ===============
=============== 以下为npm run build 跨域的解决方法 ===============
我们要打包上线:就用 npm run build 会打包成 dist 文件
但发到线上,就得用 nginx 解决跨域。
首先,下载 nginx
https://blog.csdn.net/biaoge0310/article/details/78900538
入门命令:
在 nginx 文件目录下执行以下命令
start nginx 开启nginx
nginx -s quit 退出
nginx -s reload 重启
nginx -t 检查配置文件是否成功
然后进入 nginx/conf 目录下的,找到 ngix.conf 文件
添加如下配置:
启动 nginx 服务器:start nginx
输入网址: http://localhost:9000
完美!!!!打包后也解决了。。
=============== 以上为npm run build 跨域的解决方法 ===============