You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust WASM中web_sys::fetch_with_request阻塞问题求助

排查与解决思路

核心问题:block_on阻塞浏览器主线程

浏览器是单线程事件循环模型,block_on会阻塞当前线程等待异步任务完成,这会直接卡死整个事件循环——包括Fetch请求的发起、网络响应的回调处理等所有异步操作都无法执行,导致代码永远卡在await fetch这一步,请求甚至根本没机会发送出去。

WASM在浏览器环境中运行在主线程,绝对不能用阻塞式的block_on来等待异步任务,必须遵循浏览器的异步模型。

解决步骤

1. 改用异步调用模式

移除block_on,将调用逻辑改为异步函数,通过wasm_bindgen_futures::spawn_local启动异步任务,或者暴露异步函数给JS端用async/await调用:

方式一:在WASM内部启动异步任务

use wasm_bindgen_futures::spawn_local;

#[wasm_bindgen]
pub fn load_shader(shader_name: &str) {
    spawn_local(async move {
        match fetch_as_vec_u8(&format!("http://localhost:8080/shaders/{}.vert.glsl", shader_name)).await {
            Ok(bytes) => {
                web_sys::console::log_1(&format!("Loaded shader, {} bytes", bytes.len()).into());
                // 后续处理shader字节数据
            }
            Err(e) => {
                web_sys::console::error_1(&e);
            }
        }
    });
}

方式二:暴露异步函数给JS调用

#[wasm_bindgen]
pub async fn load_shader(shader_name: &str) -> Result<Vec<u8>, JsValue> {
    fetch_as_vec_u8(&format!("http://localhost:8080/shaders/{}.vert.glsl", shader_name)).await
}

然后在JS中调用:

import { load_shader } from './your_wasm_module';

async function init() {
  try {
    const shaderBytes = await load_shader("your_shader_name");
    // 处理shader数据
  } catch (err) {
    console.error("加载shader失败:", err);
  }
}

init();

2. 补充调试日志,定位潜在问题

在关键步骤加入控制台日志,确认代码执行流程:

#[wasm_bindgen]
pub async fn fetch_as_vec_u8(resource_name: &str) -> Result<Vec<u8>, JsValue> {
    web_sys::console::log_1(&format!("Fetching: {}", resource_name).into());

    let opts = RequestInit::new()
        .method("GET")
        .mode(RequestMode::Cors);

    let request = Request::new_with_str_and_init(resource_name, &opts)?;
    request.headers().set("Accept", "application/octet-stream")?;

    web_sys::console::log_1(&"Created request, starting fetch...".into());

    let window = web_sys::window().ok_or("No window found")?;
    let resp_value = JsFuture::from(window.fetch_with_request(&request)).await?;

    web_sys::console::log_1(&"Fetch response received".into());

    // 后续转换逻辑...
}

3. 检查CORS与请求配置

  • 如果当前页面Origin(如localhost:3000)和资源服务器(localhost:8080)不同,需确保服务器返回正确的CORS响应头(如Access-Control-Allow-Origin: *或指定Origin)。
  • 同Origin请求可将RequestMode::Cors改为RequestMode::SameOrigin,避免不必要的CORS检查。

4. 确认web_sys特性开启

检查Cargo.toml中web-sys的features是否包含所需API:

[dependencies.web-sys]
version = "0.3"
features = [
  "Window",
  "Request",
  "RequestInit",
  "RequestMode",
  "Response",
  "Headers",
  "Fetch",
  "ArrayBuffer",
  "console",
]

内容的提问来源于stack exchange,提问作者Vasili Korol

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 21:57:26