我正在為Obsidian.md開發一個插件,該插件需要向需要multipart/form-data有效負載中的檔案的 API 發出 HTTP 請求。為了確保插件在移動設備上運行,我必須使用Obsidian 的 TypeScript 庫提供requestUrl的方法以確保插件在移動設備上運行,以及其他一些兼容性原因。
但是,requestUrl期望身體是 astring或 an ArrayBuffer- 有沒有辦法轉換FormData成 a stringor ArrayBuffer?還是我在構建有效載荷時采用了錯誤的方法?
介面: https ://marcus.se.net/obsidian-plugin-docs/reference/typescript/interfaces/RequestUrlParam
/** @public */
export interface RequestUrlParam {
/** @public */
url: string;
/** @public */
method?: string;
/** @public */
contentType?: string;
/** @public */
body?: string | ArrayBuffer;
/** @public */
headers?: Record<string, string>;
/**
* Whether to throw an error when the status code is >= 400
* Defaults to true
* @public
*/
throw?: boolean;
}
我的代碼:
const formData = new FormData();
const data = new Blob([await this.app.vault.adapter.readBinary(fileToTranscribe.path)]);
formData.append("audio_file", data);
const options: RequestUrlParam = {
method: "POST",
url: "http://djmango-bruh:9000/asr?task=transcribe&language=en",
contentType: "multipart/form-data",
body: formData,
};
requestUrl(options).then((response) => {
console.log(response);
}).
catch((error) => {
console.error(error);
});
當前錯誤:
Type 'FormData' is not assignable to type 'string | ArrayBuffer | undefined'.
附加參考: API Repo API Docs 該方法的作業實作
uj5u.com熱心網友回復:
我已經建立了一個解決方法,基本上我只是檢查了來自 fetch/Postman 的有效請求,現在正在手動構建相同格式的 multipart/form-data 有效負載。
可能有一個現有的庫或實用程式函式可以以更簡潔的方式執行此操作,如果我沒有找到一個,如果我需要在插件的其他部分發送檔案有效負載請求,我可以自己撰寫一個。
// This next block is a workaround to current Obsidian API limitations: requestURL only supports string data or an unnamed blob, not key-value formdata
// Essentially what we're doing here is constructing a multipart/form-data payload manually as a string and then passing it to requestURL
// I believe this to be equivilent to the following curl command: curl --location --request POST 'http://djmango-bruh:9000/asr?task=transcribe&language=en' --form 'audio_file=@"test-vault/02 Files/Recording.webm"'
// Generate the form data payload boundry string, it can be arbitrary, I'm just using a random string here
// https://stackoverflow.com/questions/3508338/what-is-the-boundary-in-multipart-form-data
// https://stackoverflow.com/questions/1349404/generate-random-string-characters-in-javascript
const N = 16 // The length of our random boundry string
const randomBoundryString = "djmangoBoundry" Array(N 1).join((Math.random().toString(36) '00000000000000000').slice(2, 18)).slice(0, N)
// Construct the form data payload as a string
const pre_string = `------${randomBoundryString}\r\nContent-Disposition: form-data; name="audio_file"; filename="blob"\r\nContent-Type: "application/octet-stream"\r\n\r\n`;
const post_string = `\r\n------${randomBoundryString}--`
// Convert the form data payload to a blob by concatenating the pre_string, the file data, and the post_string, and then return the blob as an array buffer
const pre_string_encoded = new TextEncoder().encode(pre_string);
const data = new Blob([await this.app.vault.adapter.readBinary(fileToTranscribe.path)]);
const post_string_encoded = new TextEncoder().encode(post_string);
const concatenated = await new Blob([pre_string_encoded, await getBlobArrayBuffer(data), post_string_encoded]).arrayBuffer()
// Now that we have the form data payload as an array buffer, we can pass it to requestURL
// We also need to set the content type to multipart/form-data and pass in the boundry string
const options: RequestUrlParam = {
method: 'POST',
url: 'http://djmango-bruh:9000/asr?task=transcribe&language=en',
contentType: `multipart/form-data; boundary=----${randomBoundryString}`,
body: concatenated
};
requestUrl(options).then((response) => {
console.log(response);
}).catch((error) => {
console.error(error);
});
完整來源在這里
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/527720.html
