How to send `FormData` via `Fetch`? I
How to send
FormData via Fetch? I don't see Into<JsValue> implementation on the FormData struct.Into<JsValue>FormData for a request body, so I just build a string manually (I don't send any files yet, so it supports only text fields):RequestInit.with_body results in an error because it's not of type JsValue..into() on a string to turn it into JsValue since the latter implements From<String>RequestInit.with_bodyJsValueJsValue.into()From<String>pub trait Body: fmt::Debug {
fn content_type(&self) -> String;
fn try_into(&self) -> Result<JsValue, worker::Error>;
}
#[derive(Debug)]
pub struct FormDataBody(HashMap<String, String>);
impl FormDataBody {
const BOUNDARY: &'static str = "X-INSERT-YOUR-BOUNDARY";
pub fn new() -> Self {
Self(HashMap::new())
}
pub fn append(&mut self, key: &str, value: &str) {
self.0.insert(key.to_string(), value.to_string());
}
}
impl Body for FormDataBody {
fn content_type(&self) -> String {
format!("multipart/form-data; boundary={}", Self::BOUNDARY)
}
fn try_into(&self) -> Result<JsValue, worker::Error> {
let mut body = String::new();
for (key, value) in &self.0 {
body.push_str(&format!("--{}\r\n", Self::BOUNDARY));
body.push_str(&format!("Content-Disposition: form-data; name=\"{key}\""));
body.push_str(&format!("\r\n\r\n{value}\r\n"));
}
body.push_str(&format!("--{}--\r\n", Self::BOUNDARY));
Ok(body.into())
}
} let api_url =
format!("https://api.cloudflare.com/client/v4/accounts/{}/images/v1", self.account_id);
let metadata = serde_json::to_string(&json!({"purpose": purpose.to_string()}))?;
let form = reqwest::multipart::Form::new()
.text("metadata", metadata)
.text("id", self.gen_custom_id())
.text("url", url.to_owned());
let client = reqwest::Client::new();
let response = client
.post(api_url)
.multipart(form)
.header("Authorization", format!("Bearer {}", &self.images_token))
.send()
.await?;
let response = response.error_for_status()?;