2016-12-27 28 views
1

我是新來的打字稿/ JavaScript和我想要做的二進制文件的不同部分,使用打字稿和XMLHttpRequest的多範圍請求(RFC 7233)2.如何使用typescript/javascript正確解析multipart/byteranges響應?

根據RFC 7233,一個多/字節範圍響應有以下幾點:

HTTP/1.1 206 Partial Content 
Date: Wed, 15 Nov 1995 06:25:24 GMT 
Last-Modified: Wed, 15 Nov 1995 04:58:08 GMT 
Content-Length: 1741 
Content-Type: multipart/byteranges; boundary=THIS_STRING_SEPARATES 

--THIS_STRING_SEPARATES 
Content-Type: application/pdf 
Content-Range: bytes 500-999/8000 

...the first range... 
--THIS_STRING_SEPARATES 
Content-Type: application/pdf 
Content-Range: bytes 7000-7999/8000 

...the second range 
--THIS_STRING_SEPARATES-- 

我看到兩個選項:

  1. 治療作爲二進制數據陣列的響應(設定XMLHttpRequest.responseType = "arraybuffer")的主體中,邊界字符串轉換成比納ry,在二進制數據數組中搜索由邊界字符串轉換爲二進制分隔的每個身體部分,爲每個有效負載提取標題並將它們轉換爲字符串?或者,
  2. 與上面類似,但將主體看作字符串(設置XMLHttpRequest.responseType = "text"),標識由邊界字符串分隔的主體部分,並將有效負載轉換爲二進制數據數組?

由於響應包含多個主體部分,每個主體部分都有自己的頭部(字符串)和有效負載(二進制),所以在javascript/typescript中處理/解析這種響應的正確方法是什麼?

有沒有更簡單的方法?

歡迎任何建議。謝謝!

回答

2

我什至不知道你會如何使用"arraybuffer"響應方式做到這一點,但我用這個之前解析的multipart /字節範圍響應:

function parseMultipartBody (body, boundary) { 
    return body.split(`--${boundary}`).reduce((parts, part) => { 
    if (part && part !== '--') { 
     const [ head, body ] = part.trim().split(/\r\n\r\n/g) 
     parts.push({ 
     body: body, 
     headers: head.split(/\r\n/g).reduce((headers, header) => { 
      const [ key, value ] = header.split(/:\s+/) 
      headers[key.toLowerCase()] = value 
      return headers 
     }, {}) 
     }) 
    } 
    return parts 
    }, []) 
} 

而對於使用它與一個XMLHttpRequest它可能會是這個樣子:

const client = new XMLHttpRequest() 
client.open('GET', 'example.pdf', true) 
client.setRequestHeader('Range', 'bytes=500-999,7000-7999') 
client.onreadystatechange = function() { 
    if (client.readyState == 4 && client.status === 206) { 
    const boundary = client.getResponseHeader('Content-Type').match(/boundary=(.+)$/i)[1] 
    if (boundary) console.log('PARTS', parseMultipartBody(client.resposeText, boundary)) 
    } 
} 
client.send() 

從您的示例響應的輸出應該是這樣的:

[ 
    { 
    "body": "...the first range...", 
    "headers": { 
     "content-type": "application/pdf", 
     "content-range": "bytes 500-999/8000" 
    } 
    }, 
    { 
    "body": "...the second range", 
    "headers": { 
     "content-type": "application/pdf", 
     "content-range": "bytes 7000-7999/8000" 
    } 
    } 
]