我正在寫一個雷鳥的外掛,想要在寄件時將附件轉換成網址供人下載。
我已經搞定驗證什麼的了,卡在不知道如何遵照 RFC-1867的方式上傳檔案,API都會回應101缺少適當的參數。
文件:FileStation API 文件,請直接參考第68~70頁左右
目前我的程式上傳檔案看起來會像是這樣,似乎是二進制檔案的 Content-Type 不對:
程式碼段落:
let ct = new Date();
let display_prefix = "" + ct.getFullYear() + ct.getMonth() + ct.getDate() + ct.getHours() + ct.getMinutes() + ct.getSeconds() + ""
console.log(display_prefix);
let url = base_url + "/webapi/entry.cgi?_sid=" + oauthToken;
let formData = new FormData();
formData.append('api', "SYNO.FileStation.Upload");
formData.append('version', "2");
formData.append('method', "upload");
formData.append('path', path + "/" + display_prefix + "_" +name);
formData.append('create_parents', "true");
formData.append("file", data);
console.log("hi");
let headers = {
"content-type": "application/octet-stream",
};
let fetchInfo = {
mode: "cors",
method: "POST",
headers,
body: formData,
signal: uploadInfo.abortController.signal,
};
try{
let response = await fetch(url, fetchInfo);
console.log(response)
}catch (error){
console.log(error);
}
雖然我沒試過,但猜測 header 的 Content-Type
應該要是 multipart/form-data
內部各項參數的 Content-Type
,因為已經用 FormData 了,所以它們會自動設定
你可以試試看先改 multipart/form-data
看看multipart/form-data
裡面的每一項都會有各自的 Content-Type
這部分 FormData 會自動幫我們處理
如果還是不行,需要自行指定的話,那就不能用 FormData 自動處理了
MDN 有手動產生表單的範例
剛剛測試,這樣可以變更 FormData 對檔案預設的 Content-Type
也許可以避免自己手動產生表單
//event of <input type="file" id="file-upload">
document.querySelector('#file-upload').addEventListener('change', (evt) => {
//把原始檔案包成 File 物件,並設定 type 為 application/octet-stream
let origFile = evt.target.files[0];
let submitFile = new File([origFile], origFile.name, {
type: 'application/octet-stream'
});
//傳送
let fd = new FormData();
fd.append('name', submitFile.name);
fd.append('api', "SYNO.FileStation.Upload");
fd.append('version', "2");
fd.append('method', "upload");
fd.append('path', "some/path");
fd.append('create_parents', "true");
fd.append("file", submitFile);
fetch('aaa.php', {
method: 'post',
body: fd
});
});
感謝回覆,我到最後這樣解掉的
formData.append("file", new Blob([data], {
type: "application/octet-stream"
}), name);