越學習越感覺自己瞭解的少,學習的知識不夠扎實,以前總是感覺自己瞭解CORS,前後臺交互遇到那個經典的錯誤信息腦海中就會想起需要後臺設置 cors 錯誤和代碼如下。 解決的方案也是隨口說來,也就是在後臺設置上如下類似的代碼, 直到這一次項目..搞得我是真的難受,這一篇文章本來想詳細寫一些 CORS的東 ...
越學習越感覺自己瞭解的少,學習的知識不夠扎實,以前總是感覺自己瞭解CORS,前後臺交互遇到那個經典的錯誤信息腦海中就會想起需要後臺設置 cors 錯誤和代碼如下。
解決的方案也是隨口說來,也就是在後臺設置上如下類似的代碼,
1 res.header("Access-Control-Allow-Origin", "*");
直到這一次項目..搞得我是真的難受,這一篇文章本來想詳細寫一些 CORS的東西的,沒想到跑題了。
說起來從開始接觸node到現在也有一年多的時間了,平時也是經常看文章,看書中的知識一直積累著知識。一般的後臺的東西也是知道一些的,也可以做一做。
這一次項目和java後臺對接一個手機端h5的微信公眾號的項目,後臺三個,前端三個,歷時三周,當然我是最菜的那個。
我們是前後端分離開發,我們在深圳,後臺在雲南。分離的也夠徹底了吧。
平時遇到問題你聽不懂我在說什麼,我們也不知道你們在乾什麼,經常深入交流到晚上十一點之後,好在我們都年輕,經得起折騰。好了不說廢話了,說一說這次遇到的各種問題,在這裡做一下總結。
我們和後臺關係挺好的,每次的問題都是大家一起努力解決,雖然好多問題,但是還是一條心,挺好的。
一、UI圖 VS 業務
我們是使用vue-cli開發的項目,(用框架寫代碼還是很舒服的)剛開始開發幾天我們解決了前端的靜態頁面,本來之前我們都是前端來定義項目中的數據格式的,工作不到一年的時間我見到的數據格式不是我們部長給我定義的,就是在我定義之後詢問他經過他幾次修改的,所以也沒有想那麼多,感覺數據都挺好的, 這次後臺都沒有看到UI圖,直接根據業務來寫出來的數據介面。我是真的難受了,幾張表連接一下把所有的數據都返回出來就算完成了嗎,而且也是剛開始,他們那邊也沒有數據,搞得好多欄位全部都是 null,弄的頁面很是蛋疼。
一周多的時間都是在企業微信群裡面問數據介面好了嗎?截圖噼里啪啦的就懟上去幾張。我還是感覺資料庫的關係表要按照正常的來定義,但是返給前臺的數據格式還是讓一些經驗豐富的前端來定義好一些,因為這次他們根本都沒有看UI圖導致感覺所有的介面都被重新寫了一遍一樣。而且那種格式也就是連表查詢吧。需要什麼加什麼。
二、跨域問題
搞不懂為什麼在node中那麼簡單的幾行代碼可以解決跨域的問題,到了java那裡有那麼麻煩嗎。設置一下允許所有的域訪問就可以了,後來看到他的代碼也就是加了幾個東西,他的截圖。就這一張吧
感覺也就是這個不知道他們是不是沒有做過類似的東西,跟他們說跨域,啊?我用PostMan可以訪問的到啊。我訪問你妹哦。你們怎麼寫的,然後截圖Postman的截圖,我們寫代碼使用你們的測試工具寫嗎。
三、token的驗證
因為我們做了token驗證,我不知道真正的是不是這樣的,我之前做了兩次都是我們這樣的。
我不知道那個發送過期(或者錯誤的)後臺要返給我們一個固定的狀態代表這個token過期了這一步是不是必要的,我之前做的都是這樣的,所以這次也讓他們改了,他們之前都沒有做發送過期token要怎麼樣的感覺,而且這個token的介面和另外請求數據的介面在伺服器的不同的埠上面。
前端這裡最開始是我在搞,最後面就不是我在弄了,因為他們後臺的驗證token的那些東西沒有做好卡了我們四天多進度,後面還是讓後臺先把這個東西去掉測試的其他的東西,昨天他們才加上的token,直到今天才剛把這個發佈到生產環境中。
不知道他們那裡怎麼做的,只要帶上 Authorization 就不會跨域,只要不帶這個東西就會報跨域的錯誤。指了好多次,說把那個跨域的東西放到這個token的前面,也不知道他們怎麼搞得,也不懂他們的代碼。
四、老花眼
有介面文檔總是對錯名字,搞半天還要後臺那裡給我找問題,有一個介面他們那裡字母寫錯了,我這裡搞好久不知道哪裡錯了,兩個人找半天,還有就是我寫錯了。
五、post請求數據格式
用jQuery的ajax和 axios的請求有一點不一樣,他們請求數據是不一樣的。用jQuery請求的話預設的是application/x-www-form-urlencoded的(這裡之前寫錯了,經過指正修改了),用axios就是json格式。我們是用的axios,後臺那裡識別不了json格式的。這個東西也搞了近一天當時。。我也真的是有點難受。要仔細好好看請求頭信息。
要仔細看好這兩種是不一樣的。
六、上傳圖片文件
說真的,之前工作中做的東西上傳圖片這個東西用的最多的還是微信自帶的那個上傳圖片,拿到那個文件信息直接上傳就好了,在瀏覽器裡面之前上傳過一次是上傳的 base64 位的轉碼轉成圖片了。這一次後臺又是在postman裡面測試的,當時也不知道怎麼去寫,好在知道了 FormData 這個對象可以模擬form表單發送數據。
七、vuex
在項目開始的時候都應該先看看要不要用這個東西,由於要緩存數據,在後期的時候又加上這個東西,我們三個人只有我用了,他們也有好多跨頁面的數據要保存,後面只有我自己用了一點這個。如果一開始就規定好這個就好一些了。
八、axios的options請求
我以為只有axios有那個options請求來檢測是否跨域。原來這個東西是 CORS 規範規定的,引用一下阮一峰大佬的話。
跨域資源共用 CORS 詳解 http://www.ruanyifeng.com/blog/2016/04/cors.html 點擊鏈接進入
瀏覽器將CORS請求分成兩類:簡單請求(simple request)和非簡單請求(not-so-simple request)。
只要同時滿足以下兩大條件,就屬於簡單請求。
(1) 請求方法是以下三種方法之一:
- HEAD
- GET
- POST
(2)HTTP的頭信息不超出以下幾種欄位:
- Accept
- Accept-Language
- Content-Language
- Last-Event-ID
- Content-Type:只限於三個值
application/x-www-form-urlencoded
、multipart/form-data
、text/plain
凡是不同時滿足上面兩個條件,就屬於非簡單請求。
瀏覽器對這兩種請求的處理,是不一樣的。
九、Request header filed Authorization is not allowed by Access-Control-Allow-Headers in pregglight response
本來這個錯誤沒有什麼打大不了的,真的是倒霉。肯定不是前端的問題,這個也是我這裡想要重點講一下的東西。坑死人。
1 res.header("Access-Control-Allow-Origin", "*"); 2 res.header("Access-Control-Allow-Headers", "Content-Type,Content-Length, Authorization, Accept,X-Requested-With"); 3 res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
之前那個 Access-Control-Allow-Origin : * 這裡的*可以代表允許所有的origin訪問。
我說讓後臺那裡加上 Access-Control-Allow-Headers: Authorization 這個東西應該就可以了,他加了一個 * ,也就是下麵的類似的這樣
說這個*可以代表所有的東西,找了快一天的原因了,後來又讓他加上了另外一個響應頭。
理所當然的都是不行的,後來終於找到了官網上面的文檔。終於找到錯誤的原因了。
可以看到響應頭那裡是一個 *
我相信只要是我們項目成員的人看到這個截圖絕對會終身難忘,肯定會想起我了,真的把人卡死了要。
除了那個 允許所有的域可以用 * 來表示,其他的都不可以,都必須要一個一個寫出來,後臺改了之後這個token終於加上去了。
其他還有一些粗心的小問題,也就想起來這麼多。
本來這篇文章想著重寫一下最後一個問題的心路歷程的,但是寫著寫著寫跑偏了,我們的人都挺有耐心的,也總算開發完了,把項目成果的一個二維碼截圖放到這裡,也不知道以後可以不可以訪問到。
還好我們團隊有一個厲害的人,能堅持住,後臺開發的同事也很好,介面調整的也非常及時,只要好好溝通,不要急眼,肯定會成功上線的。
2019.4.9日 20:31 記
微信掃二維碼打開項目測試實例。
附加:評論中大哥的指導, 感謝了 @Adming https://www.cnblogs.com/weapon/
這些所有的“坑”都是你對HTTP協議不瞭解,不熟悉造成的。
很多人不重視基礎,對HTTP協議只瞭解一些皮毛,成天都在折騰各種高大上的框架,張口閉口談的也是各種聽不懂的名詞,仿佛討論HTTP協議就很low一樣。
但你可知道,你們討論的這些各種框架、各種名詞都終都只是HTTP協議不同實現方式而已,asp、jsp、php、asp.net(asp.net core) 、nodejs、app、小程式、公眾號、服務號這些耳熟能詳框架(或名詞)那個不是建立在HTTP之上的(或能離開HTTP協議)。
可以這樣說,做Web開發不深入理解HTTP協議的人在這個行業的前途有限。
也不是說就一定幹不了這行了,我見過很多掛著“高級”頭銜的前端或後端開發對HTTP協議的瞭解也僅限於知道GET、POST、200、404、500而已,也能工作,看起來幹得還不錯,但和他們交流起來真的打人的衝動都有。
例如:我寫好一個api介面給他,他說調不通,返回404,我說我那個api介面只接受json格式的數據,他說我是傳的json格式啊,我說必須要在HTTP請求頭加入Content-Type:application/json,他說不會,還說我要求多,又說請求是組件封裝好了的,沒法加,老子隨手百度一下他用的那個組件的用法然後寫個示例給他就或以了(我很肯定一個成熟的前端HTTP組件不可能弱智到連設置常用的HTTP頭都不行)。
反之,你理解了HTTP協議就是找到了Web開發的捷徑,一個一通百通的閥門,深入瞭解HTTP協議對Web開發中遇到的很多問題跟本不是問題,就算有問題也可以很自然的迎刃而解,像作者文章中那些問題,在你深入瞭解HTTP協議後我相信你自己都會嘲笑自己,人窮怪屋基,沒米吃怪筲箕,
-------------
別以後了,現在就可以看,百度一下HTTP協議中文版,內容又不多,抓重點理解就可以了(後面最好買一本HTTP權威指南之類的書系統學習一下)。
其實HTTP協議就那點東西,抓重點理解就行。
1.HTTP協議三個最重要的特性:無狀態、短連接、單向(只能客戶端請求,服務端在接到請求後處理後返回,不能由伺服器端向客戶端推數據)。
2.常用的請求方式,get、post、put、delete,並瞭解get和post的區別。常見的HTTP狀態碼,200、400、500、404、403等等。
3.不管是請求還是返回總是包含header和body兩部分,又稱請求頭、請求內容,返回頭,返回內容。header是鍵值對,絕大多數情況下都是HTTP協議定義好或推薦的用法,只有在極少數的情況下需要自定義。body的格式一般和header指定的Content-Type值一致。
4.關於Content-Type,它的作用是告訴接收方用什麼方式來解析對應的body數據,很多時候可以省略,但你一定要知道有這個東西。
比如:請求頭Content-Type常用值有:application/x-www-form-urlencoded(表單提交)、multipart/form-data(文件上傳)、text/plain(純文本)、application/json。
返回常用的有:text/plain、text/xml、text/html等等(完整的Content-Type列表自行百度,只需要記一些常用的就行)。
為什麼JQuery和axios的預設Content-Type不一樣呢?因為,JQuery流行的時候還沒有大規模的應用前後端分離,所有預設還是傳統的表單提交方式(Content-Type值是application/x-www-form-urlencoded不是你說的Form-Data),而axios天生就是為前後端分離而生的,所有預設Content-Type值就是application/json。
我強調這一點的原因就是想說,這個預設在HTTP協議中並沒有強制規範,都是各個瀏覽器,Web伺服器或HTTP組件自行定義的。
也許你有疑問,我通過抓包發現好像請求頭或返回頭並沒有Content-Type樣,那是因為大多數Web伺服器或瀏覽器都可以自己根據內容推斷出格式。
5.一些其他常用的http header 鍵/值的作用。
6.POST Content-Type:Multipart/form-data 有一些特殊,它是在早先的HTTP請求中沒有定義,後來專門添加的用來文件上傳的,詳見RFC1867。
7.也就這些了