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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 前端技术 > HTML >内容正文

HTML

前端跨域问题解决方案汇总

發(fā)布時(shí)間:2024/4/14 HTML 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 前端跨域问题解决方案汇总 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

下面我以簡(jiǎn)單的兩臺(tái)node服務(wù)器來(lái)說(shuō)明如何使用nginx進(jìn)行前端跨域訪問(wèn)。

  • node1服務(wù)器 在localhost:8083上啟動(dòng)
  • const app = express(); app.get('/web/users',(req, res)=>{res.json([{name:"張三",age:12},{name:"李四",age:14}]);res.end() }) app.listen(process.env.PORT || 8083); 復(fù)制代碼

    同域下的前端代碼只需調(diào)用

    function getUsers() {var xhr=new XMLHttpRequest();xhr.open('GET', 'http://localhost:8083/web/users');xhr.send(null);xhr.onreadystatechange = function () {if (xhr.readyState == 4 && xhr.status == 200) {alert(xhr.responseText);}else {alert(xhr.statusText);}} } 復(fù)制代碼

    這里有一點(diǎn)需要關(guān)注的是,前后端代碼處在同一個(gè)域下,xhr.open() url路徑寫(xiě)成下面這樣也是可以的,它會(huì)默認(rèn)請(qǐng)求到http://localhost:8083/web/users

    xhr.open('GET', '/web/users'); 復(fù)制代碼

    下面我們將node1服務(wù)器中的web/users接口刪除:

    const app = express(); app.listen(process.env.PORT || 8083); 復(fù)制代碼

    前端此時(shí)自然無(wú)法訪問(wèn)后臺(tái)的web/users了,將報(bào)一個(gè)404錯(cuò)誤。

    下面增加一個(gè)node2服務(wù)器,在localhost:8085上啟動(dòng),同時(shí)我們將原先在8083上刪除的web/users接口搬遷到8085上:

    const app = express(); app.get('/web/users',(req, res)=>{res.json([{name:"張三",age:12},{name:"李四",age:14}]);res.end() }) app.listen(process.env.PORT || 8085); 復(fù)制代碼

    由于8085實(shí)現(xiàn)了這個(gè)接口,我們嘗試在原先8083端口下的ajax調(diào)用它試試:

    xhr.open('GET', 'http://localhost:8085/web/users'); 復(fù)制代碼

    如我們所料,瀏覽器阻止了此次行為,并拋出一個(gè)跨域錯(cuò)誤。

    難道就無(wú)法訪問(wèn)那個(gè)接口了嗎?其實(shí)服務(wù)器之間和服務(wù)器之間是可以相互調(diào)用的,阻止跨域訪問(wèn)只是在瀏覽器端做的限制而已。

    下面我通過(guò)兩種方式來(lái)實(shí)現(xiàn)如何訪問(wèn)到8085上的web/users接口。

    1 . node直接作為代理訪問(wèn)

    原理就是交由8083后端去訪問(wèn)8085端口接口,訪問(wèn)完成交給前端
    8083node后端實(shí)現(xiàn)代碼:

    npm install request --save // 需要安裝一個(gè)http request模塊 復(fù)制代碼const app = express() const request = require('request') // 訪問(wèn)此接口時(shí)通過(guò)request模塊去訪問(wèn)8085 再返回給前端。 app.get('/web/users',(req, res)=>{var url='http://localhost:8085'+req.urlconsole.log(url) // http://localhost:8085/web/usersreq.pipe(request(url)).pipe(res); }) 復(fù)制代碼

    2. jsonp方式訪問(wèn)

    就是通過(guò)script 的src,向服務(wù)器請(qǐng)求數(shù)據(jù),且這不受同源策略限制;然后服務(wù)器將相應(yīng)的數(shù)據(jù)放入指定的函數(shù)回調(diào)名中,返回給前端。說(shuō)的有點(diǎn)繞,下面通過(guò)實(shí)例講解: 8083前端請(qǐng)求8085,這里已經(jīng)不再是ajax請(qǐng)求了,而是直接加載8085上資源。

    <script>function getUsers(data) {alert(data)}</script><script src="http://localhost:8085/jsonp?callback=getUsers"></script> 復(fù)制代碼

    上述代碼第一個(gè)script標(biāo)簽定義了一個(gè)函數(shù)getUsers 但是并沒(méi)有執(zhí)行,只是定義了而已,要想有執(zhí)行能力,需要

    getUsers(data) 復(fù)制代碼

    所以我們要讓第二個(gè)標(biāo)簽script src="http://localhost:8085/jsonp?callback=getUsers" 返回getUsers(data)內(nèi)容即可,這樣第一個(gè)標(biāo)簽內(nèi)定義的函數(shù)就可以執(zhí)行了。返回接口內(nèi)容只需要放到函數(shù)參數(shù)里即可
    后臺(tái)8085實(shí)現(xiàn):

    const app = express(); const querystring=require('querystring') const url=require('url')// 處理前端jsonp請(qǐng)求 app.get('/jsonp',(req,res)=>{var qs = querystring.parse(req.url.split('?')[1]); //{callback:'getUsers'}var users=JSON.stringify([{name:"張三",age:12},{name:"李四",age:14}]) // 注意需要傳成字符串格式var callback=`${qs.callback}(${users})`res.end(callback) }) 復(fù)制代碼

    前端返回

    是不是有點(diǎn)黑魔法的味道!但是缺點(diǎn)也是明顯的,首先通過(guò)此方式有一定安全性的,通過(guò)callback后加一些亂七八糟的東西可能會(huì)有xss攻擊,最主要的是jsonp不支持post方法。

    3 .nginx反向代理器

    此方式即類似于第一種node代理方式,也是通過(guò)服務(wù)器和服務(wù)器之間通信,只是不需要8083下后臺(tái)服務(wù)器自己去訪問(wèn)8085,而是專門(mén)交給nginx,為什么?姑且認(rèn)為nginx更加專業(yè)吧! nginx配置

    server {listen 8007; # nginx啟動(dòng)端口,需要訪問(wèn)這個(gè)端口才能夠代理server_name localhost:8083; # 需要代理的服務(wù)器location / { # 如果你訪問(wèn)127.0.0.1/8002/的話nginx去請(qǐng)求proxy_pass http://localhost:8083;}location /web { #訪問(wèn)/web/aa時(shí)會(huì)映射成http://localhost:8085/web/aa;proxy_pass http://localhost:8085;}} 復(fù)制代碼

    8083請(qǐng)求路徑

    xhr.open('GET', '/web/users'); 復(fù)制代碼

    3 CORS

    CORS全稱是跨域資源共享 是一個(gè)W3C標(biāo)準(zhǔn),它規(guī)定瀏覽器允許發(fā)送ajax到不同域下的服務(wù)器來(lái)獲取數(shù)據(jù),從而克服了原來(lái)限制,使用CORS需要前后端都支持,現(xiàn)代瀏覽器基本上都支持。具體CORS的知識(shí)可以參考阮一峰博客 www.ruanyifeng.com/blog/2016/0…

    app.use('*',function (req, res, next) {res.header('Access-Control-Allow-Origin', '*'); //這個(gè)表示任意域名都可以訪問(wèn),這樣寫(xiě)不能攜帶cookie了。 //res.header('Access-Control-Allow-Origin', 'http://www.baidu.com'); //這樣寫(xiě),只有www.baidu.com 可以訪問(wèn)。res.header('Access-Control-Allow-Headers', 'Content-Type, Content-Length, Authorization, Accept, X-Requested-With , yourHeaderFeild');res.header('Access-Control-Allow-Methods', 'PUT, POST, GET, DELETE, OPTIONS');//設(shè)置方法if (req.method == 'OPTIONS') {res.send(200); }else {next();} }); 復(fù)制代碼

    或者使用現(xiàn)成的CORS模塊

    npm install cors 復(fù)制代碼var express = require('express') var cors = require('cors') var app = express()var corsOptions = {origin: 'http://www.baidu.com',optionsSuccessStatus: 200 }app.get('/products/:id', cors(corsOptions), function (req, res, next) {res.json({msg: '只有百度可以訪問(wèn)'}) })app.listen(80, function () {console.log('CORS-enabled web server listening on port 80') }) 復(fù)制代碼

    如有不正確,請(qǐng)指正^_^

    總結(jié)

    以上是生活随笔為你收集整理的前端跨域问题解决方案汇总的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

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