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

将SvelteKit嵌入Rust may minihttp时出现异常行为求助

问题排查与修复方案

核心问题分析

  • Header设置错误:may_minihttp的Response::header方法需要分别传入头字段名和值,你当前传入的是完整的"Content-Type: ..."字符串,导致浏览器无法识别正确的Content-Type,JS文件被当作text/html解析,触发模块加载错误。
  • 路由分支逻辑混乱:第一个分支是独立的if而非else if,访问根路径(空path)时,会先写入一次index.html内容,之后继续执行到最后一个分支,再次写入index.html,导致响应体重复,浏览器解析混乱,出现显示状态循环。
  • 不必要的内存泄漏:使用Box::leak构造Content-Type字符串完全多余,还会造成内存泄漏。

修复后的代码

use std::io;
use may_minihttp::{HttpService, HttpServiceFactory, Request, Response};
use rust_embed::RustEmbed; 
use mime_guess;

#[derive(RustEmbed)]
#[folder = "src/svelte/build/"]
struct Assets;

struct Router;

impl HttpService for Router {
    fn call(&mut self, req: Request, rsp: &mut Response) -> io::Result<()> {
        let path = req.path().trim_start_matches('/');
        
        match path {
            "" | "index.html" => {
                // 处理根路径和index.html请求
                if let Some(content) = Assets::get("index.html") {
                    rsp.header("Content-Type", "text/html; charset=utf-8");
                    rsp.body_mut().extend_from_slice(&content.data);
                } else {
                    rsp.status_code(404, "Not Found");
                }
            }
            p if p.contains('.') => {
                // 处理带后缀的静态资源
                if let Some(content) = Assets::get(p) {
                    let mime = mime_guess::from_path(p).first_or_octet_stream();
                    rsp.header("Content-Type", mime.as_ref());
                    rsp.body_mut().extend_from_slice(&content.data);
                } else {
                    rsp.status_code(404, "Not Found");
                }
            }
            _ => {
                // SPA路由 fallback 到index.html
                if let Some(content) = Assets::get("index.html") {
                    rsp.header("Content-Type", "text/html; charset=utf-8");
                    rsp.body_mut().extend_from_slice(&content.data);
                } else {
                    rsp.status_code(404, "Not Found");
                }
            }
        }
        
        Ok(())
    }
}

struct HttpServer;

impl HttpServiceFactory for HttpServer {
    type Service = Router;

    fn new_service(&self, _: usize) -> Self::Service {
        Router 
    }
}

fn main() {
    may::config().set_pool_capacity(500).set_stack_size(0x1000);
    let http_server = HttpServer;
    let server = http_server.start("0.0.0.0:8800").unwrap();
    server.join().unwrap();
}

修复说明

  1. 修正Header设置:所有rsp.header调用改为分传字段名和值,确保浏览器能正确识别资源类型。
  2. 重构路由逻辑:用match语句替代嵌套if-else,每个请求只会进入一个分支,避免重复写入响应体。
  3. 移除内存泄漏代码:直接使用mime.as_ref()作为Content-Type的值,无需Box::leak。
  4. 完善错误处理:每个分支添加404 fallback,避免无响应内容的情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 06:55:24