静态网页使用Node.js跨域代理服务
1. 需求背景
公司網站的本地開發版之前一直都是部署在本地電腦上Tomcat容器里的,好處就是本地搭建服務器環境接口無需做跨域請求處理,壞處就是后臺代碼的每次更新都需要拷貝一份至我的電腦覆蓋,并且本地環境與測試線環境數據仍然有所差異,在本地環境調試不便。
前天在與新入職的Java工程師討論如何分工協作的時候聊到了部署Tomcat容器到我本地的壞處,然后仔細想想我最近不是在學nodejs嘛,為何不學以致用在我本地用nodejs部署跨域代理服務呢?于是花了兩天零碎的時間研究了如何使用nodejs來實現靜態頁面的接口請求代理。 在實現跨域之前先理清楚我想實現的什么樣的功能。
2. 跨域的幾種方式
靜態網站的里的ajax請求是相對路徑,同一套代碼要在本地開發環境、測試線環境、大陸正式線、香港正式線部署。所以請求不適合使用絕對路徑。
前端跨域
前端跨域的方式有兩種
兩者的原理都是使用請求靜態資源文件的方式,用回調函數的包裝把json數據返回前端。從而騙過瀏覽器的跨域審查。使用這種方法來跨域意味著前端和后端的代碼都要根據跨域的要求來重構一番,并且只能發送GET請求,這樣的方式肯定是不可行的,因為只有在本地開發時才需要跨域,代碼部署到線上服務器后就不需要跨域了。 所以開始研究后端方案跨域。也有兩種。
后端跨域
CORS (Cross-Origin Resource Sharing)跨域資源共享,它允許瀏覽器向跨源(協議 + 域名 + 端口)服務器,發出XMLHttpRequest請求,從而克服了AJAX只能同源使用的限制。CORS需要瀏覽器和服務器同時支持,實現CORS通信的關鍵是服務器。只要服務器實現了CORS接口,就可以跨源通信。
- 參考引用:CORS(跨域資源共享)
使用CORS來實現跨域仍然需要在目標服務器的接口上配置跨域請求參數,所以實現起來要前后端配合還是比較麻煩的。而且僅僅是測試線服務器需要跨域,正式線服務器禁止跨域,這樣子修改后,后臺代碼就會出現不一致。所以此方法也棄用。
跨域代理服務,原理是把前端http請求發送給后臺的代理,讓代理代為轉發請求,從而不需要在瀏覽器上進行跨域請求。代理獲取到響應結果再轉發到前端。使用它的好處是目標服務器上的接口代碼和前端代碼都不需要做任何更改,只需開啟本地跨域代理服務即可。
每種跨域方式分析過后,覺得最可行的操作就是使用靜態資源代理服務來做前端跨域請求。
3. 使用nodejs跨域代理服務
在nginx和nodejs間選擇了后者,于是開始了在本地搭建http服務器和尋找合適的代理跨域中間件。
搭建了本地http服務后,具體怎么操作實現代理跨域其實還是沒多大思路的,于是呢就開始百度尋找案例來參考,了解了使用nodejs中間件跨域的大概思路。
先是搭建起http服務器,對訪問主機地址的網絡請求進行判斷,如果是api接口的請求時則使用中間件的代理服務進行轉發。讓中間件代為向目標服務器發起請求,響應結果再轉發至前端。
4. 代碼實現
文件結構目錄大概如此,ROOT文件夾為網頁文件夾
1.創建項目文件夾并npm初始化文件夾
mkdir demo cd demo npm init -y 復制代碼2.安裝node-http-proxy中間件 npm install http-proxy --save-dev
3.創建啟動文件proxy.js
var PORT = 3000;//定義端口號 var tatgetPATH='http://www.a.com/'//目標服務器地址 var http = require('http'); //引入http模塊 var url=require('url'); //引入url模塊 var fs=require('fs'); //引入文件模塊 var mine=require('./fileFormat').types; //文件格式字典 var path=require('path'); //引入path模塊 var httpProxy = require('http-proxy'); //跨域代理中間件var proxy = httpProxy.createProxyServer({target: tatgetPATH, //接口地址// 下面的設置用于https// ssl: {// key: fs.readFileSync('server_decrypt.key', 'utf8'),// cert: fs.readFileSync('server.crt', 'utf8')// },// secure: false });var server = http.createServer(function (request, response) {var pathname = url.parse(request.url).pathname;//訪問根目錄時改為指向首頁文件if(pathname=='/'){pathname='index.html' }// 指定根目錄var realPath = path.join("./ROOT", pathname);var ext = path.extname(realPath);ext = ext ? ext.slice(1) : 'unknown';//判斷如果是api接口訪問,則通過proxy轉發if(pathname.indexOf("./ROOT") > 0){// console.log('發起請求:',pathname)proxy.web(request, response);return;}fs.exists(realPath, function (exists) {if (!exists) {response.writeHead(404, {'Content-Type': 'text/plain'});response.write("This request URL " + pathname + " was not found on this server.");response.end();} else {fs.readFile(realPath, "binary", function (err, file) {if (err) {response.writeHead(500, {'Content-Type': 'text/plain'});response.end(err);} else {var contentType = mine[ext] || "text/plain";response.writeHead(200, {'Content-Type': contentType});response.write(file, "binary");response.end();}});}}); }); server.listen(PORT);//代理服務執行錯誤的監聽 proxy.on('error', function(err, req, res){res.writeHead(500, {'content-type': 'text/plain'});console.log(err);res.end('Something went wrong. And we are reporting a custom error message.'); }); console.log("Server runing at port: " + PORT + "."+tatgetPATH); 復制代碼引入文件格式字典 fileFormat.js
exports.types = {"css": "text/css","gif": "image/gif","html": "text/html","ico": "image/x-icon","jpeg": "image/jpeg","jpg": "image/jpeg","js": "text/javascript","json": "application/json","pdf": "application/pdf","png": "image/png","svg": "image/svg+xml","swf": "application/x-shockwave-flash","tiff": "image/tiff","txt": "text/plain","wav": "audio/x-wav","wma": "audio/x-ms-wma","wmv": "video/x-ms-wmv","xml": "text/xml","woff": "application/x-woff","woff2": "application/x-woff2","tff": "application/x-font-truetype","otf": "application/x-font-opentype","eot": "application/vnd.ms-fontobject"}; 復制代碼代碼寫完后運行proxy.js即可通過跨域代理服務來實現本地調用不同域服務器的接口了。
- 源碼主要參考了下面這篇文章,十分感謝該作者提供的方案。 Node.js配合node-http-proxy解決本地開發ajax跨域問題
5. 總結
跨域的解決方案有很多,具體選擇哪一種方案還是根據實際的情況來進行分析。
以前還沒學習nodejs的時候,遇到跨域問題能想到的解決方法就是使用ajax的jsonp,需要后端返回的接口加上回調函數,前端再通過通過函數對數據進行接收。改起來十分之麻煩。
前端若是懂得后端的一些知識,便能夠使用更多的解決方案來解決問題。web開發中包括了前端和后端,能夠熟練使用兩端的技能,才能夠在web開發中游刃有余。
總結
以上是生活随笔為你收集整理的静态网页使用Node.js跨域代理服务的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Qtum量子链应邀出席2019棉兰区块链
- 下一篇: Android:手把手教你 实现Acti