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

Java Socket搭建本地HTTP服务器时HTML关联静态资源加载失败问题

问题根因分析
  • 请求路径映射缺失:浏览器加载完index.html后,会自动发送GET请求获取页面关联的资源,比如你的css文件对应请求路径是/myStyles.css,你的代码仅对/路径做了映射到Resources/index.html的处理,其余路径直接用请求路径作为本地文件路径读取,系统找不到/myStyles.css这个根路径下的文件,自然抛出异常。
  • 响应头格式不符合HTTP规范:HTTP协议要求响应头和响应体之间必须有空行,你之前的代码写完响应头直接传输文件内容,没有空行分隔,浏览器会解析异常。
  • 响应头Content-Type固定错误:当前所有响应的Content-Type都写死为text/html,即使后续资源请求通了,浏览器也会将css、图片等资源当做HTML文件解析,无法正常渲染样式和图片。
  • ServerSocket创建逻辑不合理:你把new ServerSocket(8080)放在了while死循环内部,每次处理完一个请求就关闭服务端口再重新监听,会导致并发请求处理异常。
修复方案

修改后完整代码

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

public class HttpServer {
    // 根据文件后缀返回对应Content-Type
    private static String getContentType(String fileName) {
        if (fileName.endsWith(".html") || fileName.endsWith(".htm")) {
            return "text/html; charset=UTF-8";
        } else if (fileName.endsWith(".css")) {
            return "text/css; charset=UTF-8";
        } else if (fileName.endsWith(".png")) {
            return "image/png";
        } else if (fileName.endsWith(".jpg") || fileName.endsWith(".jpeg")) {
            return "image/jpeg";
        } else if (fileName.endsWith(".js")) {
            return "application/javascript; charset=UTF-8";
        } else {
            return "application/octet-stream";
        }
    }

    public static void main(String[] args) throws IOException {
        // ServerSocket移到循环外,只初始化一次
        ServerSocket sSocket = new ServerSocket(8080);
        while (true) {
            Socket cSocket = sSocket.accept();
            OutputStream oStream = cSocket.getOutputStream();
            PrintWriter out = new PrintWriter(oStream, true);
            Scanner in = new Scanner(new InputStreamReader(cSocket.getInputStream()));

            // 解析请求行
            String command = in.next();
            String fileName = in.next();
            String protocol = in.next();

            // 路径映射处理:所有请求都映射到Resources目录下
            if (fileName.equals("/")) {
                fileName = "Resources/index.html";
            } else {
                // 去掉路径开头的/,拼上Resources前缀
                fileName = "Resources/" + fileName.substring(1);
            }

            // 404异常处理
            File file = new File(fileName);
            if (!file.exists()) {
                out.println("HTTP/1.1 404 Not Found");
                out.println("Server: My Server");
                out.println("Content-Type: text/html; charset=UTF-8");
                // 响应头和响应体之间的空行
                out.println();
                out.println("<h1>404 资源不存在</h1>");
            } else {
                FileInputStream fis = new FileInputStream(file);
                // 返回响应头
                out.println("HTTP/1.1 200 OK");
                out.println("Server: My Server");
                out.println("Content-Type: " + getContentType(fileName));
                // 响应头和响应体之间的空行,必须保留
                out.println();
                out.flush(); // 先将响应头刷出再传输二进制内容
                fis.transferTo(oStream);
                fis.close();
            }

            // 关闭资源
            in.close();
            out.close();
            cSocket.close();
        }
    }
}

额外修正点

你index.html中的link标签属性写错了,content="text/css"需要改为type="text/css",否则浏览器可能无法正确识别样式文件:

<link rel="stylesheet" type="text/css" href="./myStyles.css"/>

你原本能正常读取index.html,说明IntelliJ运行配置的工作目录就是项目根目录,不需要额外修改IDE配置。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 22:48:02