0

這是捲曲例子正常工作職位:如何使用的multipart/form-data的頭和FORMDATA使用取

curl -X POST \ 
    <url> \ 
    -H 'authorization: Bearer <token>' \ 
    -H 'content-type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW' \ 
    -F [email protected] \ 
    -F userId=<userId> 

我試圖重現使用isomorphic-fetch這一請求。

我試過下面的代碼:

const formData = new FormData(); 
formData.append('file', file); 
formData.append('userId', userId); 

return fetch(`<url>`, {  
    method: 'POST', 
    headers: { 
    'Content-Length': file.length 
    'Authorization: Bearer <authorization token>', 
    'Content-Type': 'multipart/form-data' 
    }, 
    body: formData 
})` 

我爲了產生傳遞到FormDatafile使用fs.readFileSync

前面的示例返回一個錯誤消息,指出嵌入所述令牌(通過標頭中發送)的userId不匹配userIdformData通過了401 HTTP狀態代碼(未授權的)。

所以我的懷疑是到達REST API的FormData沒有適當的形成。

該問題可能與Content-Length頭有關,但我沒有找到更好的方法來計算的話(如果我不使用Content-Length頭,我收到了411 HTTP狀態代碼Content-Length頭丟失)。

可能是由於Content-Length標題中的值不正確而導致失敗的情況?

關於爲什麼這是失敗或如何更好地調試它的任何其他建議?

如果需要進一步的信息來澄清這個問題,請提問。

UPDATE

我一直在使用該方法formData.getLengthSync()

試過form-data模塊,以獲得正確的Content-Length值然而,問題依舊(401錯誤HTTP狀態代碼響應)。

+0

降'Content-Type'請求頭部需要由瀏覽器自動生成以包含多部分邊界。我想如果你放棄這個和Content-Length標題你應該沒問題。 – idbehold

+0

我已經試過,沒有成功,當我不發送Content-Length頭時,API會返回一個411錯誤的HTTP狀態碼:服務器拒絕接受沒有定義的Content-長度「 – rfc1484

+0

嘗試將Content-Length設置爲12345.無論您上傳到的服務器設計得不是很好。 – idbehold

回答

2

如果你打開你的網絡督察,運行該代碼片段,並提交你應該看到Content-Length正確設置形式:

const foo = document.getElementById('foo') 
 
foo.addEventListener('submit', (e) => { 
 
    e.preventDefault() 
 
    const formData = new FormData(foo) 
 
    formData.append('userId', 123) 
 
    fetch('//example.com', { 
 
    method: 'POST', 
 
    body: formData 
 
    }) 
 
})
<form id="foo"> 
 
    <input id="file" type="file" name="file"/><br><br> 
 
    <button type="submit">Submit</button> 
 
</form>

+0

因此,如果我理解正確,問題不在於客戶端實現,而是與REST API實現(這意味着當Content-Length頭未被傳遞時,它不應返回「411」錯誤HTTP狀態碼) – rfc1484

+0

@ rfc1484我在說你應該在你的'fetch()'配置文件中指定的唯一頭文件是'Authorization'頭文件,因爲'Content-Length'和'Content-Type'頭文件都會被瀏覽器自動設置。所以請嘗試從代碼中刪除這兩行代碼。 – idbehold

+0

我明白了,但我已經嘗試過這個解決方案,但它沒有起作用(它返回了之前提到的'411'錯誤)。由於我使用單元測試來測試它,所以我認爲問題在於請求是在服務器端執行的,所以在這種情況下,瀏覽器不會自動設置標題,因爲它不會通過瀏覽器並直接使用'node-fetch'庫(在執行服務器端請求時,由'isomorphic-fetch'使用的底層庫)。因此,雖然單元測試目前失敗,但這可能會起到'客戶端'的作用。 – rfc1484

相關問題