xhr提供了2個用來獲取響應頭部的方法:getAllResponseHeaders和getResponseHeader。前者是獲取 response 中的所有header 字段,后者只是獲取某個指定 header 字段的值。另外,getResponseHeader(header)的header參數不區分大小寫。
DOMString getAllResponseHeaders();
DOMString getResponseHeader(DOMString header);
你是否遇到過下面的坑兒?——反正我是遇到了。。。
使用getAllResponseHeaders()看到的所有response header與實際在控制臺 Network 中看到的 response header 不一樣
使用getResponseHeader()獲取某個 header 的值時,瀏覽器拋錯Refused to get unsafe header "XXX"
經過一番尋找最終在 Stack Overflow找到了答案。
原因1:W3C的 xhr 標準中做了限制,規定客戶端無法獲取 response 中的 Set-Cookie、Set-Cookie2這2個字段,無論是同域還是跨域請求;
原因2:,規定對于跨域請求,客戶端允許獲取的response header字段只限于“simple response header”和“Access-Control-Expose-Headers” (兩個名詞的解釋見下方)。
“simple response header“包括的 header 字段有:Cache-Control,Content-Language,Content-Type,Expires,Last-Modified,Pragma;
“Access-Control-Expose-Headers“:首先得注意是”Access-Control-Expose-Headers“進行跨域請求時響應頭部中的一個字段,對于同域請求,響應頭部是沒有這個字段的。這個字段中列舉的 header 字段就是服務器允許暴露給客戶端訪問的字段。
所以getAllResponseHeaders()只能拿到限制以外(即被視為safe)的header字段,而不是全部字段;而調用getResponseHeader(header)方法時,header參數必須是限制以外的header字段,否則調用就會報Refused to get unsafe header的錯誤。
如何指定xhr.response的數據類型
有些時候我們希望xhr.response返回的就是我們想要的數據類型。比如:響應返回的數據是純JSON字符串,但我們期望最終通過xhr.response拿到的直接就是一個 js 對象,我們該怎么實現呢?
有2種方法可以實現,一個是level 1就提供的overrideMimeType()方法,另一個是level 2才提供的xhr.responseType屬性。
xhr.overrideMimeType()
overrideMimeType是xhr level 1就有的方法,所以瀏覽器兼容性良好。這個方法的作用就是用來重寫response的content-type,這樣做有什么意義呢?比如:server 端給客戶端返回了一份document或者是 xml文檔,我們希望最終通過xhr.response拿到的就是一個DOM對象,那么就可以用xhr.overrideMimeType('text/xml; charset = utf-8')來實現。
再舉一個使用場景,我們都知道xhr level 1不支持直接傳輸blob二進制數據,那如果真要傳輸 blob 該怎么辦呢?當時就是利用overrideMimeType方法來解決這個問題的。
下面是一個獲取圖片文件的代碼示例:
代碼示例中xhr請求的是一張圖片,通過將 response 的 content-type 改為’text/plain; charset=x-user-defined’,使得 xhr 以純文本格式來解析接收到的blob 數據,最終用戶通過this.responseText拿到的就是圖片文件對應的二進制字符串,最后再將其轉換為 blob 數據。
xhr.responseType
responseType是xhr level 2新增的屬性,用來指定xhr.response的數據類型,目前還存在些兼容性問題,可以參考本文的【XMLHttpRequest的兼容性】這一小節。那么responseType可以設置為哪些格式呢,我簡單做了一個表,如下:
評論