亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JavaScript > 正文

淺談Koa2框架利用CORS完成跨域ajax請求

2019-11-19 14:13:57
字體:
來源:轉載
供稿:網友

實現跨域ajax請求的方式有很多,其中一個是利用CORS,而這個方法關鍵是在服務器端進行配置。

本文僅對能夠完成正??缬騛jax響應的,最基本的配置進行說明(深層次的配置我也不會)。

CORS將請求分為簡單請求和非簡單請求,可以簡單的認為,簡單請求就是沒有加上額外請求頭部的get和post請求,并且如果是post請求,請求格式不能是application/json(因為我對這一塊理解不深如果錯誤希望能有人指出錯誤并提出修改意見)。而其余的,put、post請求,Content-Type為application/json的請求,以及帶有自定義的請求頭部的請求,就為非簡單請求。

簡單請求的配置十分簡單,如果只是完成響應就達到目的的話,僅需配置響應頭部的Access-Control-Allow-Origin即可。

如果我們在http://localhost:3000 域名下想要訪問 http://127.0.0.1:3001 域名??梢宰鋈缦屡渲茫?/p>

app.use(async (ctx, next) => { ctx.set('Access-Control-Allow-Origin', 'http://localhost:3000'); await next();});

然后用ajax發起一個簡單請求,例如post請求,就可以輕松的得到服務器正確響應了。

實驗代碼如下:

$.ajax({  type: 'post',  url: 'http://127.0.0.1:3001/async-post' }).done(data => {  console.log(data);})

服務器端代碼:

router.post('/async-post',async ctx => { ctx.body = { code: "1", msg: "succ" }});

然后就能得到正確的響應信息了。

這時候如果看一下請求和響應的頭部信息,會發現請求頭部多了個origin(還有一個referer為發出請求的url地址),而響應頭部多了個Access-Control-Allow-Origin。

現在可以發送簡單請求了,但是要想發送非簡單請求還是需要其他的配置。

當第一次發出非簡單請求的時候,實際上會發出兩個請求,第一次發出的是preflight request,這個請求的請求方法是OPTIONS,這個請求是否通過決定了這一個種類的非簡單請求是否能成功得到響應。

為了能在服務器匹配到這個OPTIONS類型的請求,因此需要自己做一個中間件來進行匹配,并給出響應使得這個預檢能夠通過。

app.use(async (ctx, next) => { if (ctx.method === 'OPTIONS') { ctx.body = ''; } await next();});

這樣OPTIONS請求就能夠通過了。

如果檢查一下preflight request的請求頭部,會發現多了兩個請求頭。

Access-Control-Request-Method: PUTOrigin: http://localhost:3000

要通過這兩個頭部信息與服務器進行協商,看是否符合服務器應答條件。

很容易理解,既然請求頭多了兩個信息,響應頭自然也應該有兩個信息相對應,這兩個信息如下:

Access-Control-Allow-Origin: http://localhost:3000Access-Control-Allow-Methods: PUT,DELETE,POST,GET

第一條信息和origin相同因此通過。第二條信息對應Access-Controll-Request-Method,如果在請求的方式包含在服務器允許的響應方式之中,因此這條也通過。兩個約束條件都滿足了,所以可以成功的發起請求。

至此為止,相當于僅僅完成了預檢,還沒發送真正的請求呢。

真正的請求當然也成功獲得了響應,并且響應頭如下(省略不重要部分)

Access-Control-Allow-Origin: http://localhost:3000Access-Control-Allow-Methods: PUT,DELETE,POST,GET

請求頭如下:

Origin: http://localhost:3000

這就很顯而易見了,響應頭部信息是我們在服務器設定的,因此是這樣。

而客戶端因為剛才已經預檢過了,所以不需要再發Access-Control-Request-Method這個請求頭了。

這個例子的代碼如下:

$.ajax({   type: 'put',   url: 'http://127.0.0.1:3001/put'  }).done(data => {   console.log(data);});

服務器代碼:

app.use(async (ctx, next) => {  ctx.set('Access-Control-Allow-Origin', 'http://localhost:3000');  ctx.set('Access-Control-Allow-Methods', 'PUT,DELETE,POST,GET');  await next();});

至此我們完成了能夠正確進行跨域ajax響應的基本配置,還有一些可以進一步配置的東西。

比如,到目前為止,每一次非簡單請求都會實際上發出兩次請求,一次預檢一次真正請求,這就比較損失性能了。為了能不發預檢請求,可以對如下響應頭進行配置。

Access-Control-Max-Age: 86400

這個響應頭的意義在于,設置一個相對時間,在該非簡單請求在服務器端通過檢驗的那一刻起,當流逝的時間的毫秒數不足Access-Control-Max-Age時,就不需要再進行預檢,可以直接發送一次請求。

當然,簡單請求時沒有預檢的,因此這條代碼對簡單請求沒有意義。

目前代碼如下:

app.use(async (ctx, next) => { ctx.set('Access-Control-Allow-Origin', 'http://localhost:3000'); ctx.set('Access-Control-Allow-Methods', 'PUT,DELETE,POST,GET'); ctx.set('Access-Control-Max-Age', 3600 * 24); await next();});

到現在為止,可以對跨域ajax請求進行響應了,但是該域下的cookie不會被攜帶在請求頭中。如果想要帶著cookie到服務器,并且允許服務器對cookie進一步設置,還需要進行進一步的配置。

為了便于后續的檢測,我們預先在http://127.0.0.1:3001這個域名下設置兩個cookie。注意不要錯誤把cookie設置成中文(剛才我就設置成了中文,結果報錯,半天沒找到出錯原因)

然后我們要做兩步,第一步設置響應頭Access-Control-Allow-Credentials為true,然后在客戶端設置xhr對象的withCredentials屬性為true。

客戶端代碼如下:

$.ajax({   type: 'put',   url: 'http://127.0.0.1:3001/put',   data: {    name: '黃天浩',    age: 20   },   xhrFields: {    withCredentials: true   }  }).done(data => {   console.log(data);  });

服務端如下:

app.use(async (ctx, next) => {  ctx.set('Access-Control-Allow-Origin', 'http://localhost:3000');  ctx.set('Access-Control-Allow-Methods', 'PUT,DELETE,POST,GET');  ctx.set('Access-Control-Allow-Credentials', true);  await next();});

這時就可以帶著cookie到服務器了,并且服務器也可以對cookie進行改動。但是cookie仍是http://127.0.0.1:3001域名下的cookie,無論怎么操作都在該域名下,無法訪問其他域名下的cookie。

現在為止CORS的基本功能已經都提到過了。

一開始我不知道怎么給Access-Control-Allow-Origin,后來經人提醒,發現可以寫一個白名單數組,然后每次接到請求時判斷origin是否在白名單數組中,然后動態的設置Access-Control-Allow-Origin,代碼如下:

app.use(async (ctx, next) => { if (ctx.request.header.origin !== ctx.origin && whiteList.includes(ctx.request.header.origin)) {  ctx.set('Access-Control-Allow-Origin', ctx.request.header.origin);  ctx.set('Access-Control-Allow-Methods', 'PUT,DELETE,POST,GET');  ctx.set('Access-Control-Allow-Credentials', true);  ctx.set('Access-Control-Max-Age', 3600 * 24); } await next();});

這樣就可以不用*通配符也可匹配多個origin了。

注意:ctx.origin與ctx.request.header.origin不同,ctx.origin是本服務器的域名,ctx.request.header.origin是發送請求的請求頭部的origin,二者不要混淆。

最后,我們再稍微調整一下自定義的中間件的結構,防止每次請求都返回Access-Control-Allow-Methods以及Access-Control-Max-Age,這兩個響應頭其實是沒有必要每次都返回的,只是第一次有預檢的時候返回就可以了。

調整后順序如下:

app.use(async (ctx, next) => { if (ctx.request.header.origin !== ctx.origin && whiteList.includes(ctx.request.header.origin)) {  ctx.set('Access-Control-Allow-Origin', ctx.request.header.origin);  ctx.set('Access-Control-Allow-Credentials', true); } await next();});app.use(async (ctx, next) => { if (ctx.method === 'OPTIONS') {  ctx.set('Access-Control-Allow-Methods', 'PUT,DELETE,POST,GET');  ctx.set('Access-Control-Max-Age', 3600 * 24);  ctx.body = ''; } await next();});

這樣就減少了多余的響應頭。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
97精品国产97久久久久久| 日韩免费在线电影| 欧美亚洲日本黄色| 亚洲视频第一页| 91po在线观看91精品国产性色| 亚洲国产日韩精品在线| 国产91精品久久久久| 亚洲xxxx妇黄裸体| 久久91亚洲精品中文字幕奶水| 欧美日韩免费观看中文| 国产日韩在线亚洲字幕中文| 欧美亚洲一区在线| 高清欧美性猛交xxxx黑人猛交| 两个人的视频www国产精品| 欧美精品亚州精品| 最近2019中文免费高清视频观看www99| 国产91av在线| 最近2019中文字幕在线高清| 欧美裸体xxxx极品少妇| 日韩av网站大全| 日本久久久久久| 色悠悠久久88| 国产乱肥老妇国产一区二| 欧美极品xxxx| 亚洲欧美中文日韩v在线观看| 亚洲欧美精品在线| 亚洲欧美三级伦理| 永久免费看mv网站入口亚洲| 精品无人国产偷自产在线| 在线播放日韩欧美| 欧美成人免费播放| 日韩精品视频在线观看免费| 国产在线视频2019最新视频| 亚洲欧美日韩中文在线| 国外成人在线直播| 亚洲国语精品自产拍在线观看| 亚洲人成电影在线观看天堂色| 欧美亚洲国产日本| 亚洲a级在线播放观看| 久久久久久18| 日韩国产高清视频在线| 精品久久久精品| 国产一区二区三区丝袜| 日本欧美国产在线| 色久欧美在线视频观看| 在线观看亚洲视频| 欧美激情乱人伦| 91中文字幕一区| 国产精品入口福利| 欧美夫妻性视频| 日韩中文字幕视频| 中文字幕精品网| 国产成人一区二区| 日韩欧美国产网站| 精品中文字幕在线观看| 国产精品小说在线| 国产精品视频男人的天堂| 日韩一中文字幕| 欧美日韩黄色大片| 最好看的2019的中文字幕视频| 92版电视剧仙鹤神针在线观看| 九九久久精品一区| 成人日韩在线电影| 国产乱肥老妇国产一区二| 午夜精品在线视频| 永久免费看mv网站入口亚洲| 日韩高清人体午夜| 国产精品美乳一区二区免费| 国产精品稀缺呦系列在线| 中文字幕日韩免费视频| 国产精品狼人色视频一区| 久热精品视频在线| 国产精品一区二区3区| 国产日韩欧美在线| 91av在线影院| 国产精品久久久久久久av电影| 欧美黑人又粗大| 精品久久久久久亚洲精品| 日韩中文字幕在线视频| 国产91亚洲精品| 亚洲国产欧美在线成人app| 中日韩美女免费视频网址在线观看| 国产精品久久不能| 97国产精品久久| 国产精品99导航| 欧美老女人xx| 色综合伊人色综合网站| 国产精品丝袜视频| 日韩在线一区二区三区免费视频| 欧美精品免费播放| 亚洲免费视频观看| 国产亚洲精品久久久久久| 色樱桃影院亚洲精品影院| 国产日产欧美a一级在线| 免费不卡在线观看av| 一区二区欧美日韩视频| 国产z一区二区三区| 日韩国产高清污视频在线观看| 日韩视频欧美视频| 亚洲女成人图区| 亚洲国产精品电影在线观看| 亚洲精品av在线播放| 色综合久久中文字幕综合网小说| 亚洲电影成人av99爱色| 国产成人精品综合久久久| 亚洲国产成人一区| 久久视频在线播放| 在线电影av不卡网址| 久久av在线看| 欧美国产日韩xxxxx| 国产精品久久国产精品99gif| 日韩av理论片| 亚洲精品网址在线观看| 成人国产精品免费视频| 91在线观看免费高清完整版在线观看| 欧美乱大交xxxxx| 亚洲国产日韩欧美在线99| 55夜色66夜色国产精品视频| 日本久久久久亚洲中字幕| 久久影视电视剧凤归四时歌| 色狠狠久久aa北条麻妃| 欧美一级免费视频| 高清欧美性猛交xxxx| 美日韩丰满少妇在线观看| 亚洲天堂av综合网| 日韩在线高清视频| 97视频免费在线观看| 欧美激情中文网| 亚洲香蕉伊综合在人在线视看| 国产精品免费福利| 91沈先生作品| 日本精品久久中文字幕佐佐木| 情事1991在线| 国产成人久久精品| 中国日韩欧美久久久久久久久| 亚洲爱爱爱爱爱| 日韩大陆欧美高清视频区| 色妞欧美日韩在线| 精品国产依人香蕉在线精品| 欧美日韩国产麻豆| 欧美电影免费观看高清完整| 久久青草精品视频免费观看| 97人人做人人爱| 久久中文字幕一区| 久久九九全国免费精品观看| 国产精品国产自产拍高清av水多| 欧美在线播放视频| 91国产精品视频在线| 91在线免费网站| 亚洲免费高清视频| 国内精品视频久久| 成人av在线网址| 久久久成人精品视频| 精品久久久视频| 最新国产成人av网站网址麻豆| 在线观看久久av| 日韩av中文字幕在线免费观看| 精品国产户外野外| 国产精品日韩专区| 国产精品一二三视频| 国产精品毛片a∨一区二区三区|国| 97久久超碰福利国产精品…| 蜜臀久久99精品久久久无需会员| 国产精品久久久久久亚洲调教|