跟随Rust Book教程搭建Web Server时HTML无法正常渲染求助
问题描述
我正在跟随《Rust Book》第20章的Web服务器教程学习,但遇到HTML无法正常渲染的问题。处理连接的代码与教程完全一致:
fn handle_connection(mut stream: TcpStream) { let buf_reader = BufReader::new(&mut stream); let http_request: Vec<_> = buf_reader .lines() .map(|result| result.unwrap()) .take_while(|line| !line.is_empty()) .collect(); let status_line = "HTTP/1.1 200 OK\r\n\r\n"; let contents = fs::read_to_string("hello.html").unwrap(); let length = contents.len(); let response = format!("{status_line}\r\nContent-Length: {length}\r\n\r\n{contents}"); stream.write_all(response.as_bytes()).unwrap(); }
对应的hello.html内容如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>Hello!</title> </head> <body> <h1>Hello!</h1> <p>Hi from Rust</p> </body> </html>
运行服务器后,使用Brave浏览器请求时,页面显示HTML源码而非渲染后的效果。曾怀疑HTML缩进问题,但VS Code扩展自动格式化后的格式应无误。作为Rust和Web服务器新手,恳请相关解决建议。
解决方法
问题出在HTTP响应的格式错误,以及缺少关键响应头:
- 重复的分隔符:你的
status_line里已经包含了\r\n\r\n(响应头与响应体的分隔符),但构造response时又额外添加了一次,导致分隔符变成\r\n\r\n\r\n,浏览器无法正确解析响应结构。 - 缺少Content-Type头:没有告诉浏览器返回的内容是HTML,浏览器默认按纯文本处理,所以直接显示源码。
修改后的handle_connection代码如下:
use std::fs; use std::io::{BufRead, BufReader, Write}; use std::net::TcpStream; fn handle_connection(mut stream: TcpStream) { let buf_reader = BufReader::new(&mut stream); let http_request: Vec<_> = buf_reader .lines() .map(|result| result.unwrap()) .take_while(|line| !line.is_empty()) .collect(); // 修正状态行,仅保留状态信息,不提前添加分隔符 let status_line = "HTTP/1.1 200 OK"; let contents = fs::read_to_string("hello.html").unwrap(); let length = contents.len(); // 添加Content-Type头,严格遵循HTTP响应格式:状态行 → 头部字段 → 分隔符 → 响应体 let response = format!( "{status_line}\r\nContent-Length: {length}\r\nContent-Type: text/html; charset=utf-8\r\n\r\n{contents}" ); stream.write_all(response.as_bytes()).unwrap(); }
修改后重新运行服务器,浏览器即可正常渲染HTML内容。
额外注意:
- 确保
hello.html与Rust可执行文件在同一目录,或使用正确的文件路径。 - 后续学习要严格遵循HTTP协议规范:每个响应头字段为
键: 值格式,结尾加单个\r\n;响应头与响应体之间必须是两个连续的\r\n。
内容的提问来源于stack exchange,提问作者camdenmcgath
相关产品推荐
相关产品推荐

