三種主流的跨域解決方案(vue-cli3 package.json中配置跨域)
最近學習nodejs的express框架生蚁,對CORS(跨域資源共享Cross-origin resource sharing
)比較感興趣泪幌,看過上面的文章后在本地測試發(fā)現(xiàn)很多容易忽略的問題導致無法實現(xiàn)跨域八千,現(xiàn)將解決方案記錄如下:
跨域的解決方案:
1.CORS跨域資源共享(后端設置)
弊端:
如果Access-Control-Allow-Origin
設置單一源不能同時設置多個
如果 Access-Control-Allow-Origin
設置為 * 不允許攜帶 cookie
1.1 使用cors插件處理
1.2 使用自定義中間件設置響應頭處理
1.3 使用app.use('*',callback)全局攔截處理響應頭
具體實現(xiàn)如下(三個方法選擇其一即可):
后端代碼實現(xiàn)
服務端node.js
的src/app.js
啟動文件配置如下:
const express = require('express')
const bodyParser = require('body-parser')//用于解析請求體的中間件,否則無法獲取req.body
const app = express()
const models = require('./db/models/index.js')
const baseUrl = '/todo_api'
const cors = require('cors')
//1.cors插件處理跨域
app.use(cors())
//2.自定義中間件處理跨域
/* let allowCrossDomain = function(req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.header('Access-Control-Allow-Headers', 'Content-Type, token');
res.header('Access-Control-Allow-Credentials','true');
console.log('zqf123')
next();
};
app.use(allowCrossDomain); */
//3.app.all('*')全局攔截處理跨域
/* app.all('*', (req, res, next)=>{
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.header('Access-Control-Allow-Headers', 'Content-Type, token');
res.header('Access-Control-Allow-Credentials',true);
console.log('res', res)
next();
}) */
前端代碼實現(xiàn):
在封裝的全局攔截請求http.js里設置絕對路徑的的baseURL
前綴地址哄辣,一般為server
地址,同時可以根據需要設置header
的值挖藏。
import axios from 'axios'
// 全局請求頭設置
axios.defaults.headers = {
'Content-Type': 'application/json',
'token': 'zqf666',
}
//統(tǒng)一設置請求前綴
axios.defaults.baseURL = "http://127.0.0.1:3030/todo_api"
最后將http.js引入到前端項目的入口文件里
//react項目的src/index.js文件
import './http/http.js'
//vue項目的src/main.js文件
import './http/http.js'
容易出現(xiàn)的問題:
由于全局設置了請求頭Content-Type
和token
,而在node.js
里最開始處理CORS時設置為res.header('Access-Control-Allow-Headers', 'Content-Type');
導致瀏覽器控制臺報錯無法跨域,在postman工具上測試又可以拿到返回的數據,最后用firefox瀏覽器打開測試了一下雖然還是跨域但是瀏覽器給出了具體的原因意狠,終于解決。
2.Http Proxy 代理
弊端:
只能在本地開發(fā)使用疮胖,線上部署需要搭配Nginx
等代理服務器
2.1 在vue項目中使用代理
2.1.1根目錄下創(chuàng)建配置文件vue.config.js
module.exports = {
"lintOnSave": false,//忽略eslint代碼檢查
"devServer": {
"proxy": {
"/api": {
"target": "http://127.0.0.1:3030/",//代理的地址
"changeOrigin": true,
"ws": true,
"pathRewrite": {
"^/api": ""
}
}
}
}
}
2.1.2不使用vue.config.js配置文件
在 vue-cli3
中取消了配置文件 vue.config.js
环戈,網上的跨域處理多為新建配置文件 vue.config.js
,如果不想增加配置文件澎灸,則可以在package.json增加配置:
- 在
package.json
中加入vue
字段(下面的代碼段) - 如果請求的地址不是
/api
院塞,借助pathRewrite
將/api
替換 - 用
axios
進行網絡請求,在封裝axios
時設置baseURL: '/api'
而非絕對路徑
"eslintConfig": {
//eslint代碼檢查規(guī)則性昭,代替.eslintrc.js配置文件
},
"vue": {
//代替vue.config.js配置文件
"lintOnSave": false,//忽略eslint代碼檢查
"devServer": {
"proxy": {
"/api": {
"target": "http://127.0.0.1:3030/",//代理的地址
"changeOrigin": true,
"ws": true,
"pathRewrite": {
"^/api": ""
}
}
}
}
}
容易出現(xiàn)的問題:
1.該方法必須在vue-cli3
腳手架生成的項目(目錄下沒有vue.config.js文件)里使用拦止;
- 在
package.json
的vue字段里設置代理,則vue.config.js
文件不能存在,否則package.json
的配置會被忽略汹族,如下圖:
2.2 在react項目中使用代理
2.2.1在 package.json 中加入 proxy字段并設置相關代理
react官方文檔說明
2.2.2在 在config配置文件里設置相關代理
通過
create-react-app
腳手架安裝的react
項目只有node_modules
萧求、public
、src
文件夾顶瞒,很多配置文件都沒有了夸政,那是因為webpack,babel
等都是被creat-react-app
封裝到了react-scripts
這個項目當中搁拙,包括基本啟動命令都是通過調用react-scripts這個依賴下面的命令進行啟動秒梳。通過npm run eject
將原本creat react app
對webpack,babel
等相關配置的封裝彈射出來箕速,然后就可以在項目的目錄下config配置文件酪碘,修改代理即可。3.使用插件代理
后端實現(xiàn):
1.安裝中間件http-proxy-middleware:
npm i http-proxy-middleware -d
2.在src/app.js
中引入中間件并添加配置
// 引用依賴
var express = require('express');
var createProxyMiddleware = require('http-proxy-middleware');
var app = express();
// 創(chuàng)建代理設置中間件選項
var exampleProxy = createProxyMiddleware ( {
target: 'http://127.0.0.1:3030', // 目標服務器 host
changeOrigin: true, // 默認false盐茎,是否需要改變原始主機頭為目標URL
ws: true, // 是否代理websockets
pathRewrite: {
'^/api' : '', // 重寫請求
},
};);
// 使用代理
app.use('/api', exampleProxy);
app.listen(3000);
請求地址示例:
axios.get(/api/xxx)
前端實現(xiàn):
axios前綴設置
axios.header.baseURL='/api'