通过Socket传输后仅部分CSS样式生效的问题求助
本地网页样式正常,但Socket发送后仅部分样式生效的问题
本地直接打开网页时样式显示完全正常,但通过Socket将HTML和CSS文件发送到客户端后,只有部分样式生效。以下是加载文件并发送给客户端的代码:
// accept connection from a client Socket socket = server.accept(); // if connection is stable, read and write from client try (OutputStream out = socket.getOutputStream()) { InputStream in = socket.getInputStream(); var line = new BufferedReader(new InputStreamReader(in)).readLine(); String file = line.substring(5, line.length() - 9); if (file.equals("")) { file = "index.html"; } // load script file from file directory StringBuilder contentBuilder = new StringBuilder(); try { BufferedReader webpage = new BufferedReader(new FileReader(file)); String str; while ((str = webpage.readLine()) != null) { contentBuilder.append(str); } webpage.close(); } catch (IOException e) { e.printStackTrace(); } String content = contentBuilder.toString(); // construct valid HTML response message final String CRLF = "\r\n"; // 13, 10 String response = "HTTP/1.1 200 OK" + CRLF + // status line: HTTP_VERSION RESPONSE_CODE RESPONSE_MESSAGE "Content-Length: " + content.getBytes().length + CRLF + // header CRLF + content + CRLF + CRLF; // write HTML message to the client out.write(response.getBytes()); }
补充说明1:HTML中引入了在线字体样式表:
<link rel="stylesheet" href="style.css"> <link rel="stylesheet" src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
补充说明2:尝试将Content-Length改为content.getBytes(StandardCharsets.UTF_8).length,还尝试添加CRLF.getBytes(StandardCharsets.UTF_8).length,但均无效果。
问题原因及解决方法
HTTP请求行解析错误:
代码中用line.substring(5, line.length() - 9)硬编码截取请求路径,完全不符合HTTP请求行规范。HTTP请求行格式为GET /请求路径 HTTP/1.1,正确做法是按空格分割字符串提取路径:String[] parts = line.split(" "); String file = parts[1].substring(1); // 去掉开头的/ if (file.isEmpty()) { file = "index.html"; }硬截取会导致客户端请求
style.css时,服务器返回错误内容,直接导致本地CSS样式加载失败。在线样式表标签属性错误:
引入外部样式表必须用href属性,而非src。错误的<link rel="stylesheet" src="...">会导致在线字体样式表无法加载,相关字体样式失效,修正为:<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">文件读取编码不统一:
FileReader使用系统默认编码读取文件,若HTML/CSS文件为UTF-8编码,而系统默认编码不一致,会导致内容乱码,部分样式解析失败。需指定UTF-8编码读取:BufferedReader webpage = new BufferedReader( new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8) );响应内容长度与实际发送不一致:
- 响应构造时,内容后多添加了
CRLF + CRLF,HTTP规范中头部结束后仅需一个CRLF接内容,多余换行会被客户端当成内容的一部分,干扰解析。 - 计算
Content-Length和发送响应时,必须统一使用UTF-8编码,避免长度计算错误,同时建议添加Content-Type头帮助客户端识别文件类型:
其中byte[] contentBytes = content.getBytes(StandardCharsets.UTF_8); String response = "HTTP/1.1 200 OK" + CRLF + "Content-Length: " + contentBytes.length + CRLF + "Content-Type: " + getContentType(file) + CRLF + CRLF; out.write(response.getBytes(StandardCharsets.UTF_8)); out.write(contentBytes);getContentType可根据文件后缀返回对应类型,比如HTML用text/html; charset=UTF-8,CSS用text/css; charset=UTF-8。
- 响应构造时,内容后多添加了
内容的提问来源于stack exchange,提问作者Kristian Norved
相关产品推荐
相关产品推荐

