日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

静态网页使用Node.js跨域代理服务

發(fā)布時間:2025/7/14 编程问答 48 豆豆
生活随笔 收集整理的這篇文章主要介紹了 静态网页使用Node.js跨域代理服务 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

1. 需求背景

公司網(wǎng)站的本地開發(fā)版之前一直都是部署在本地電腦上Tomcat容器里的,好處就是本地搭建服務(wù)器環(huán)境接口無需做跨域請求處理,壞處就是后臺代碼的每次更新都需要拷貝一份至我的電腦覆蓋,并且本地環(huán)境與測試線環(huán)境數(shù)據(jù)仍然有所差異,在本地環(huán)境調(diào)試不便。

前天在與新入職的Java工程師討論如何分工協(xié)作的時候聊到了部署Tomcat容器到我本地的壞處,然后仔細想想我最近不是在學nodejs嘛,為何不學以致用在我本地用nodejs部署跨域代理服務(wù)呢?于是花了兩天零碎的時間研究了如何使用nodejs來實現(xiàn)靜態(tài)頁面的接口請求代理。 在實現(xiàn)跨域之前先理清楚我想實現(xiàn)的什么樣的功能。

2. 跨域的幾種方式

靜態(tài)網(wǎng)站的里的ajax請求是相對路徑,同一套代碼要在本地開發(fā)環(huán)境、測試線環(huán)境、大陸正式線、香港正式線部署。所以請求不適合使用絕對路徑。

前端跨域

前端跨域的方式有兩種

  • 通過script標簽跨域
  • 通過jsonp跨域
  • 兩者的原理都是使用請求靜態(tài)資源文件的方式,用回調(diào)函數(shù)的包裝把json數(shù)據(jù)返回前端。從而騙過瀏覽器的跨域?qū)彶?。使用這種方法來跨域意味著前端和后端的代碼都要根據(jù)跨域的要求來重構(gòu)一番,并且只能發(fā)送GET請求,這樣的方式肯定是不可行的,因為只有在本地開發(fā)時才需要跨域,代碼部署到線上服務(wù)器后就不需要跨域了。 所以開始研究后端方案跨域。也有兩種。

    后端跨域

  • CORS跨域資源共享
  • 跨域代理服務(wù)
  • CORS (Cross-Origin Resource Sharing)跨域資源共享,它允許瀏覽器向跨源(協(xié)議 + 域名 + 端口)服務(wù)器,發(fā)出XMLHttpRequest請求,從而克服了AJAX只能同源使用的限制。CORS需要瀏覽器和服務(wù)器同時支持,實現(xiàn)CORS通信的關(guān)鍵是服務(wù)器。只要服務(wù)器實現(xiàn)了CORS接口,就可以跨源通信。

    • 參考引用:CORS(跨域資源共享)

    使用CORS來實現(xiàn)跨域仍然需要在目標服務(wù)器的接口上配置跨域請求參數(shù),所以實現(xiàn)起來要前后端配合還是比較麻煩的。而且僅僅是測試線服務(wù)器需要跨域,正式線服務(wù)器禁止跨域,這樣子修改后,后臺代碼就會出現(xiàn)不一致。所以此方法也棄用。

    跨域代理服務(wù),原理是把前端http請求發(fā)送給后臺的代理,讓代理代為轉(zhuǎn)發(fā)請求,從而不需要在瀏覽器上進行跨域請求。代理獲取到響應(yīng)結(jié)果再轉(zhuǎn)發(fā)到前端。使用它的好處是目標服務(wù)器上的接口代碼和前端代碼都不需要做任何更改,只需開啟本地跨域代理服務(wù)即可。

    每種跨域方式分析過后,覺得最可行的操作就是使用靜態(tài)資源代理服務(wù)來做前端跨域請求。

    3. 使用nodejs跨域代理服務(wù)

    在nginx和nodejs間選擇了后者,于是開始了在本地搭建http服務(wù)器和尋找合適的代理跨域中間件。

    搭建了本地http服務(wù)后,具體怎么操作實現(xiàn)代理跨域其實還是沒多大思路的,于是呢就開始百度尋找案例來參考,了解了使用nodejs中間件跨域的大概思路。

    先是搭建起http服務(wù)器,對訪問主機地址的網(wǎng)絡(luò)請求進行判斷,如果是api接口的請求時則使用中間件的代理服務(wù)進行轉(zhuǎn)發(fā)。讓中間件代為向目標服務(wù)器發(fā)起請求,響應(yīng)結(jié)果再轉(zhuǎn)發(fā)至前端。

    4. 代碼實現(xiàn)

    文件結(jié)構(gòu)目錄大概如此,ROOT文件夾為網(wǎng)頁文件夾

    1.創(chuàng)建項目文件夾并npm初始化文件夾

    mkdir demo cd demo npm init -y 復制代碼

    2.安裝node-http-proxy中間件 npm install http-proxy --save-dev

    3.創(chuàng)建啟動文件proxy.js

    var PORT = 3000;//定義端口號 var tatgetPATH='http://www.a.com/'//目標服務(wù)器地址 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, //接口地址// 下面的設(shè)置用于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轉(zhuǎn)發(fā)if(pathname.indexOf("./ROOT") > 0){// console.log('發(fā)起請求:',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);//代理服務(wù)執(zhí)行錯誤的監(jiān)聽 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即可通過跨域代理服務(wù)來實現(xiàn)本地調(diào)用不同域服務(wù)器的接口了。

    • 源碼主要參考了下面這篇文章,十分感謝該作者提供的方案。 Node.js配合node-http-proxy解決本地開發(fā)ajax跨域問題

    5. 總結(jié)

    跨域的解決方案有很多,具體選擇哪一種方案還是根據(jù)實際的情況來進行分析。

    以前還沒學習nodejs的時候,遇到跨域問題能想到的解決方法就是使用ajax的jsonp,需要后端返回的接口加上回調(diào)函數(shù),前端再通過通過函數(shù)對數(shù)據(jù)進行接收。改起來十分之麻煩。

    前端若是懂得后端的一些知識,便能夠使用更多的解決方案來解決問題。web開發(fā)中包括了前端和后端,能夠熟練使用兩端的技能,才能夠在web開發(fā)中游刃有余。

    總結(jié)

    以上是生活随笔為你收集整理的静态网页使用Node.js跨域代理服务的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。