iT邦幫忙

0

JavaScript 使用 application/octet-stream 上傳檔案

  • 分享至 

  • xImage

我正在寫一個雷鳥的外掛,想要在寄件時將附件轉換成網址供人下載。
我已經搞定驗證什麼的了,卡在不知道如何遵照 RFC-1867的方式上傳檔案,API都會回應101缺少適當的參數。
文件:FileStation API 文件,請直接參考第68~70頁左右

目前我的程式上傳檔案看起來會像是這樣,似乎是二進制檔案的 Content-Type 不對:
https://ithelp.ithome.com.tw/upload/images/20221130/20088395TCzWSqQRps.jpg
程式碼段落:

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);
  }
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 個回答

0
淺水員
iT邦大師 6 級 ‧ 2022-12-01 00:18:01

雖然我沒試過,但猜測 header 的 Content-Type 應該要是 multipart/form-data
內部各項參數的 Content-Type ,因為已經用 FormData 了,所以它們會自動設定

看更多先前的回應...收起先前的回應...
黃彥儒 iT邦高手 1 級 ‧ 2022-12-01 00:26:13 檢舉

但根據API文件,一個請求要包含兩種Type,就不知道如何是好

淺水員 iT邦大師 6 級 ‧ 2022-12-01 00:31:58 檢舉

你可以試試看先改 multipart/form-data 看看
multipart/form-data 裡面的每一項都會有各自的 Content-Type
這部分 FormData 會自動幫我們處理

如果還是不行,需要自行指定的話,那就不能用 FormData 自動處理了
MDN 有手動產生表單的範例

淺水員 iT邦大師 6 級 ‧ 2022-12-01 01:09:58 檢舉

剛剛測試,這樣可以變更 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
    });
});
黃彥儒 iT邦高手 1 級 ‧ 2022-12-01 12:00:57 檢舉

感謝回覆,我到最後這樣解掉的

formData.append("file", new Blob([data], {
    type: "application/octet-stream"
  }), name);

我要發表回答

立即登入回答