題圖 From 極客時間 From Clmjavascript
前端開發者在工做中經常遇到跨域的問題,通常咱們遇到跨域問題主要使用如下辦法來解決:html
一、jsonp前端
二、corsvue
三、配置代理服務器。java
jsonp不是很靈活,只能發送get請求,不能發送psot請求,而cors雖然能夠支持多種請求格式,可是若是請求攜帶cookie的話,還須要服務端和客戶端分別配置一下,我的感受也很麻煩。node
相對於前兩種,使用代理服務器解決跨域問題就簡單了好多。react
瀏覽器因爲同源策略的緣由,不一樣域名之間發送ajax請求,響應的數據不會被瀏覽器加載。而服務器向服務器發送請求則沒有同源策略的限制。jquery
下圖即是代理服務器的原理了:nginx
代理服務器只是起一箇中轉做用,配置代理服務器的方法有不少種,好比利用apache、nginx、tomcat等等,今天給你們介紹的是用nodejs配置代理服務器,用nodejs配置代理服務器,咱們須要藉助兩個npm包,一個是web開發框架express,一個是express中間件http-proxy-middleware 。git
首先第一步咱們先用express搭建兩個服務器,一個靜態資源服務器端口號爲3000,一個接口服務器端口號爲5000,靜態資源服務器代碼以下:
var express = require('express');
var app = express();
app.use(express.static('./public'));
app.listen(3000);
而且在public文件夾下新建a.html,而且在頁面中使用jquery,使用jquery發送ajax向接口服務器發送測試請求。
a.html代碼以下:
接着搭建接口服務器,接口服務器端口號爲5000,代碼以下:
觀察代碼,咱們設計了三個接口,都是get請求,只是url不一樣。
此時啓動靜態資源服務器和接口服務器,而後訪問靜態資源服務器下面的a.html,結果如圖:
如圖所示,發生跨域了,此時在靜態資源服務器中安裝http-proxy-middleware 中間件,並將其集成到靜態資源服務器中。
代碼以下:
此時重啓靜態資源服務器,並將啊,a.html頁面中發送ajax的地址稍微改動一下,如圖:
觀察代碼:咱們代碼原來是直接請求5000端口服務器的數據,如今將其改爲相對路徑,相對於當前網頁所在的服務器,當前的網頁所在的靜態服務器端口爲3000。
當咱們訪問:http://localhost:3000/a.html,結果如圖:
看ajax請求的地址是如何拼接的:
得出結論:相對路徑會被自動拼接。
再看請求的結果,成功了:
成功跨域了,固然這樣說不嚴謹,瀏覽器並無參與跨域,而是頁面中的ajax請求的地址仍是3000端口的服務,只不過是3000端口的服務接收到請求,將其轉發給了5000端口的服務,並將5000端口的服務結果原封不動的返還給了瀏覽器。
回顧上面的代碼,咱們只是在靜態資源服務器中應用了http-proxy-middleware中間件,這個中間件的使用很是簡單,分爲以下幾步:
一、安裝並引入到項目中。
二、經過app.use掛載中間件,這裏須要注意的是,在掛載這個中間件的時候,app.use須要設置一個前置路由,和項目原本的路由做區分。
調用這個中間件的時候須要設置幾個經常使用參數:
一、target,指的是目標網站,或者被代理的網站。
二、changeOrigin是否更改host。默認爲false,不重寫。
三、pathRewrite路徑重寫,這個特性看需求。
簡單配置一下:
若是這樣配置,當a.html中發送請求時,這樣寫:
這個請求會被靜態資源服務器轉化爲:
http://localhost:5000/api/a
也就是說若是不設置pathRewrite的話,頁面中的請求地址會被原封不動的追加到目標服務器地址的後面。
而若是真正的接口地址是這樣的:
http://localhost:5000/b
代理服務器該如何配置呢?
此時在頁面中發送求請:
此時根據代理服務的重寫規則,最終請求的地址爲:
http://localhost:5000/b
以上即是pathRewrite的做用。
接着看changeOrigin的做用,當咱們將changeOrigin設置爲true時,咱們在接口服務器打印req.headers,看看結果如何:
仔細觀察host是localhost:5000,而將changeOrigin改成false呢?再次打印req.headers:
此時查看host是localhost:3000,
changeOrigin就是是否重寫請求頭中的host,代理服務器會在請求頭中加入相應Host首部,而後目標服務器就能夠根據這個首部來區別要訪問的站點了。假如你在本地80端口起了apache服務器,服務器配了兩個虛擬站點a.com b.com,設置代理以後而且changeOrigin爲true 。此時就能夠正確方法訪問到虛擬主機下的文檔內容。不然訪問a b站點等同於訪問localhost。固然若是你的服務器沒有配置虛擬主機,徹底能夠省略這個參數,就像上面演示的代碼,徹底能夠省略這個參數。由於接口服務器並無設置虛擬主機。
以上即是用nodejs搭建代理服務器的知識了,這個http-proxy-middleware中間件用的很普遍,在vue-cli或者create-react-app生成的項目中都內置了這個中間件,配置規則基本和上面相同,你們有問題能夠留言。
天天進步一點點,你們共勉,雖然放假了,可是不能鬆懈呀。
代碼地址 https://github.com/clm1100/corsAndProxy/tree/master/proxy
https://segmentfault.com/q/1010000005271156
https://segmentfault.com/q/1010000012607105