Ini adalah contoh CURL yang berfungsi dengan baik:
curl -X POST \
<url> \
-H 'authorization: Bearer <token>' \
-H 'content-type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW' \
-F [email protected] \
-F userId=<userId>
Saya mencoba mereproduksi permintaan ini menggunakan isomorphic-fetch.
Saya sudah mencoba kode berikut:
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
})`
Saya menggunakan fs.readFileSync
untuk menghasilkan file
yang diteruskan ke FormData
.
Contoh sebelumnya mengembalikan kode status HTTP 401
(tidak sah) dengan pesan kesalahan yang mengatakan bahwa userId
yang disematkan dalam token (dikirim melalui header) tidak cocok dengan userId
yang diteruskan dari formData
.
Jadi kecurigaan saya adalah bahwa FormData
yang masuk ke REST API tidak dibentuk secara memadai.
Masalahnya mungkin terkait dengan header Content-Length
, tetapi saya tidak menemukan cara yang lebih baik untuk menghitungnya (jika saya tidak menggunakan header Content-Length
, saya mendapatkan kode status HTTP 411
Content-Length
header hilang).
Mungkinkah ini gagal karena nilai yang salah dalam header Content-Length
?
Adakah saran lain tentang mengapa hal ini gagal atau bagaimana cara men-debugnya dengan lebih baik?
Jika diperlukan info lebih lanjut untuk mengklarifikasi masalah ini, silakan tanyakan saja.
UPDATE
Saya sudah mencoba modul form-data untuk mendapatkan nilai PanjangKonten
yang tepat menggunakan metode formData.getLengthSync()
Namun masalahnya tetap sama (respon kode status HTTP error 401
).
Jika Anda membuka network inspector, jalankan potongan kode ini, dan kirimkan formulir, Anda akan melihat bahwa Content-Length
sudah diatur dengan benar:
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>
Saya membenturkan kepala saya ke dinding yang sama, khususnya menggunakan isomorphic-fetch
pada node untuk POST formulir multipart. Kunci bagi saya adalah menemukan .getHeaders()
. Perhatikan bahwa deskripsi NPM untuk form-data
menyarankan bahwa itu akan bekerja tanpa ini, tetapi tampaknya tidak, setidaknya tidak di node (saya pikir browser menyuntikkan header?).
// image is a Buffer containing a PNG image
// auth is the authorization token
const form_data = new FormData();
form_data.append("image", png, {
filename: `image.png`,
contentType: 'application/octet-stream',
mimeType: 'application/octet-stream'
});
const headers = Object.assign({
'Accept': 'application/json',
'Authorization': auth,
}, form_data.getHeaders());
try {
const image_res = await fetch(url, {
method: 'POST',
headers: headers,
body: form_data
});
if (!image_res.ok) {
const out = await image_res.json();
console.dir(out);
return;
}
}
catch (e) {
console.error(`Chart image generation exception: ${e}`);
}