rust 'web_sys::Url::create_object_url_with_blob(&blob)'未正确设置二进制数据的格式

yyhrrdl8  于 2023-02-16  发布在  其他
关注(0)|答案(1)|浏览(125)

下面的代码:

let bytes: Vec<u8> = load_file_as_bytes("mydoc.docx"); // This gets a byte vec representation of the file mydoc.docx
let uint8arr =  unsafe { js_sys::Uint8Array::view(&bytes) };
let js_value = wasm_bindgen::JsValue::from(uint8arr);
let blob = Blob::new_with_u8_array_sequence_and_options(
    &js_value,
    web_sys::BlobPropertyBag::new().type_("application/vnd.openxmlformats-officedocument.wordprocessingml.document"),
).unwrap();
let download_url = web_sys::Url::create_object_url_with_blob(&blob).unwrap();

当我点击链接时,下载的文件是一堆写在Word文档中的字节。
这些字节用于表示word文档本身,而不是作为明文写入其中。
这将被编译为Wasm并在浏览器中运行。
如果我将字节表示为Base64编码的文本,并创建一个<a>元素,其中的href指向字符串,那么我将得到正确的表示。

let base64_string = base64::encode(&file.bytes);
let download_url = format!("data:{};base64,{}",file.mime_type,base64_string);
// ... set href = &download_url inside dom

但对于超过几KB的文件来说,这是非常慢的,并且随着添加更多文件而变得更慢。
正确的Rust-〉JS转换是什么,以使用create_object_url_with_blob(),使其按预期工作?

von4xj4u

von4xj4u1#

看起来正确的方法是先将Uint8Array推送到js_sys::Array,因为js_sys::Array实现了JsCast,所以可以直接在blob中使用它。
我假设这来自于js_sys中JavaScript类型的某种内部表示,并且问题中的代码行为可能默认将字节数组视为文本。
工作代码:

let uint8arr = js_sys::Uint8Array::new(&unsafe { js_sys::Uint8Array::view(&bytes) }.into()); 
let array = js_sys::Array::new();
array.push(&uint8arr.buffer());
let blob = Blob::new_with_u8_array_sequence_and_options(
&array,
web_sys::BlobPropertyBag::new().type_("application/vnd.openxmlformats-officedocument.wordprocessingml.document"),
).unwrap();
let download_url = web_sys::Url::create_object_url_with_blob(&blob).unwrap();

这将导致字节实际用作Word文档,而不是写入空的Word文档。

相关问题