1、跨域和同源策略
什么是同源策略?
同源策略是指瀏覽器處於安全考慮的情況下,只允許本域下的借口進行交互。不同源的客戶端在沒有授權的情況下是不允許獲取對方資源的。
本域指的是什么?
同協議:例如相同的http或https
同域名:例如https://baidu.com/aaa 和 https://baidu.com/bbb
同端口:例如8080端口
一個示例:
跨域解決方案:
JSONP
CORS
nginx反向代理
降域
postMessage
JSONP:最早的解決方案,利用script標簽可以跨域的原理實現,只支持get請求
CORS:同源策略
優勢:
在服務端進行控制是否允許跨域,可自定義規則
支持各種請求方式
缺點:
會產生額外的請求
阮一峰對CORS的解析:http://www.ruanyifeng.com/blog/2016/04/cors.html
nginx反向代理
思路是:利用nginx反向代理把跨域為不跨域,支持各種請求方式
缺點:需要在nginx進行額外配置,語義不清晰
降域和postMessage:
https://www.jianshu.com/p/7666e1ffb8c6
當沒api接口遇到跨域問題時,會報XMLHttpRequest跨域提示:
當使用CORS策略,解決跨域問題時,我的做法是在服務端設置允許訪問的接口地址:

app.use(async (ctx, next) => { //添加允許請求頭 // ctx.append('Access-Control-Allow-Origin', '*') // ctx.append('Access-Control-Allow-Headers', 'Content-Type, Content-Length, Authorization, Accept, X-Requested-With , yourHeaderFeild') // ctx.append('Access-Control-Allow-Methods', 'PUT,POST,GET,DELETE,OPTIONS,PATCH') // //ctx.append('Content-Type', 'application/json;charset=utf-8') // console.log(`Process ${ctx.request.method} ${ctx.request.url}...`); // logger.info(`Process ${ctx.request.method} ${ctx.request.url}...`) //http 預請求處理(post/put/delete 請求在正式請求之前會先發送一個OPTIONS的預請求,只需要把這個OPTIONS的預請求正常返回,后續的請求就會正常執行) if (ctx.request.method === 'OPTIONS') { ctx.body = "OK" } else { //繼續執行api請求 await next(); } });
因為項目中使用的是vue+node.js實現,而vue自身可以設置proxy實現跨域,所以最終采用vue proxy+nginx反向代理,實現跨域
2、Vue 設置代理實現本地跨域
當前項目使用vue-cli3.0版本構建
首先在根目錄下創建vue.config.js文件,這個配置文件會在運行項目的時候自動加載

module.exports = { runtimeCompiler: true, publicPath: '/', // 設置打包文件相對路徑 devServer: { open: process.platform === 'darwin', host: '127.0.0.1', port: 3000, // open: true, //配置自動啟動瀏覽器 proxy: { '/api': { // target: process.env.VUE_APP_BASE_URL, //對應自己的接口 target: 'http://www.xxx.com', //對應自己的接口 changeOrigin: true, ws: true, pathRewrite: { '^/api': '' } } } }, }
解釋:
proxy對象標識,對/api 開頭的接口實現代理
target:’’,代理的接口地址,
changeOrigin:true,是否跨域
secure:false, 如果是https接口,需要配置這個參數
pathRewrite:{},//重寫api路徑,因為原來接口中不存在’/api’,我們人為加上去就是為了標識哪些接口需要實現代理,但是真正訪問接口的時候還是要把接口uri中的‘/api’替換為‘’
我們不僅可以為’/api’實現代理,也可以為其他具有同類功能的接口實現代理,比如我們的接口是發布在多個微服務中的,就需要我們設置多個代理地址,
這時,就不能對axios設置統一的baseURL
//axios.defaults.baseURL = ‘’
在使用axios請求接口的時候,如果需要跨域,則在請求接口前加載‘/api’,例如:
const server=’/api’
const uri=server+’/ patient_survey/findByPage’
axios.post(uri).then(res=>{})
配置完成之后本地就可以跨域訪問了,
通過瀏覽器F12查看請求地址為:
但是實際的接口請求地址為:devServer.proxy.target中的地址
所以實際請求的uri為:http:www.xxx.com/patient_survey/findByPage
3、vue+nginx實現服務端跨域
但是把vue項目打包發布之后,調用接口會提示404錯誤,這時還需要在nginx中做一下反向代理
在服務器中找到nginx的配置文件nginx.config
在需要添加反向代理的配置項中添加如下:
location /api {
rewrite ^.+api/?(.*)$ /$1 break; //可選參數,正則驗證地址
include uwsgi_params; //可選參數,uwsgi是服務器和服務端應用程序的通信協議,規定了怎么把請求轉發給應用程序和返回
proxy_pass http://www.xxx.com;// 此處修改為自己的請求地址,必填
}

server { listen 80; server_name xxx.com; charset utf8; location / { root /data/release/xxx; index index.html; proxy_pass http://127.0.0.1:8003; } location /api { rewrite ^.+api/?(.*)$ /$1 break; include uwsgi_params; proxy_pass http://www.xxx.com; } error_page 404 /404.html; location = /40x.html { } error_page 500 502 503 504 /50x.html; location = /50x.html { } }
設置完成后 重啟nginx
- nginx –s reload
完成后服務器應該也能實現跨域
參考:
https://www.cnblogs.com/zhaohongcheng/p/11250161.html
4、vue配置環境變量
在實現vue的跨域訪問之后,為了方便本機調試和發布,可以在vue中設置不同的環境變量,使項目在不同的環境中自動調用不同的接口地址
需要文件:
在vue項目根目錄下創建三個文件
.env 無論開發環境還是生成環境都會加載
.env.development 開發環境加載這個文件
.env.production 生成環境加載這個文件
如果需要其他環境,可以繼續添加其他環境的配置文件
.env 文件內容:
NODE_ENV = production
.env.development 文件內容:
NODE_ENV = development
VUE_APP_BASE_URL = http://localhost:3000/
.env.production 文件內容:
NODE_ENV = production
VUE_APP_BASE_URL = http://www.xxx.com/
(其中’VUE_APP_’是固定前綴,不可以更改)
文件加載順序:
首先加載.env文件,判斷當前的項目環境,
如果是開始環境,則繼續加載.env.development的內容,
如果是生產環境,則加載.env.production的內容,
ps:測試發現,當前的系統環境並不是.env文件中的NODE_ENV =xxx 確定的,而是根據實際情況決定,
如在ide中使用npm run serve調試,則加載的是.env.development文件
如果執行npm run build 之后發布到服務器,則加載的是.env.production文件
pageage.json的scripts部分如下
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
在項目main.js文件可以打開查看當前的系統變量:
console.log('process.env',process.env)
設置完之后,在開始的vue.config.js代理文件中,將target指向改為: process.env.VUE_APP_BASE_URL
之后,vue會根據執行環境的不同自動加載相應的接口地址