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

请求服务器时出现net::ERR_CONNECTION_CLOSED错误的修复方案

修复登录请求的net::ERR_CONNECTION_CLOSED错误

问题背景

搭建了非安全聚焦的简易登录界面服务端与客户端,客户端发送请求时触发net::ERR_CONNECTION_CLOSED错误。相关代码及现象如下:

服务端代码(src/index.mjs)

import { createServer } from "http";

const hostname = "127.0.0.1";
const port = 1337;

const server = createServer((req, res) => {
  if (req.method === "GET" && req.url === "/login") {
    const { username, password } = req.query;
    console.log("usr:" + username + "pass:" + password);
    // Perform authentication logic here
    if (
      username === "read_password" &&
      password === "security_isnt_what_i_want"
    ) {
      // Authentication successful
      res.statusCode = 200;
      res.setHeader("Content-Type", "text/plain");
      res.end("Login successful");
    } else {
      // Authentication failed
      res.statusCode = 401;
      res.setHeader("Content-Type", "text/plain");
      res.end("Login failed");
    }
  } else {
    // Handle other requests
    res.statusCode = 404;
    res.setHeader("Content-Type", "text/plain");
    res.end("Not Found");
  }
});

server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});

客户端代码(index.html)

<!DOCTYPE html>
<body>
  <script>
    let xhr = new XMLHttpRequest();

    xhr.onreadystatechange = function () {
      if (this.readyState == 4 && this.status == 200) {
        console.log(this.responseText);
      }
    };

    let loginForm = `
    <form>
      <label>Username: </label>
      <input type="text" name="username" />
      <label>Password: </label>
      <input type="password" name="password" />
      <input type="submit" value="Login" />
    </form>
    `;

    let loginDiv = document.createElement("div");
    loginDiv.innerHTML = loginForm;

    document.body.appendChild(loginDiv);
    document.querySelector("form").addEventListener("submit", (e) => {
      e.preventDefault();
      let username = document.querySelector('input[name="username"]').value;
      let password = document.querySelector('input[name="password"]').value;
      xhr.open("POST", "https://127.0.0.1:1337/login", true);
      xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
      xhr.send("username=" + username + "&password=" + password);
    });
  </script>

</body>

现象

  • 预期:输入正确用户名(read_password)和密码(security_isnt_what_i_want)后,开发者控制台无错误输出
  • 实际:触发POST https://127.0.0.1:1337/login net::ERR_CONNECTION_CLOSED错误

错误原因

  1. 协议不匹配:服务端是HTTP服务,客户端却用HTTPS发起请求,导致连接无法建立
  2. 请求方法不匹配:服务端仅处理GET方法的/login请求,但客户端发送的是POST请求,服务端无对应处理逻辑,直接返回404或导致连接异常关闭
  3. 服务端未正确解析请求参数:即使改为GET请求,原生HTTP模块不会自动解析URL查询参数,req.query会是undefined;POST请求的表单数据也未做解析处理

修复步骤

1. 修复客户端请求

将请求协议从https改为http,与服务端一致:

// 原代码
xhr.open("POST", "https://127.0.0.1:1337/login", true);
// 修改后
xhr.open("POST", "http://127.0.0.1:1337/login", true);

2. 修复服务端逻辑

修改服务端以支持POST请求,并解析表单数据:

import { createServer } from "http";
import { parse } from "querystring"; // 引入querystring模块解析表单数据

const hostname = "127.0.0.1";
const port = 1337;

const server = createServer((req, res) => {
  // 统一处理GET和POST的/login请求
  if (req.url === "/login") {
    let params = {};

    if (req.method === "GET") {
      // 解析GET请求的URL参数
      const url = new URL(req.url, `http://${hostname}:${port}`);
      params.username = url.searchParams.get("username");
      params.password = url.searchParams.get("password");
      handleAuth(params, res);
    } else if (req.method === "POST") {
      // 解析POST请求的表单数据
      let body = "";
      req.on("data", chunk => {
        body += chunk.toString();
      });
      req.on("end", () => {
        params = parse(body);
        handleAuth(params, res);
      });
      return; // 等待数据接收完成再处理,提前返回避免执行后续逻辑
    }
  } else {
    res.statusCode = 404;
    res.setHeader("Content-Type", "text/plain");
    res.end("Not Found");
  }
});

// 提取认证逻辑为单独函数
function handleAuth(params, res) {
  const { username, password } = params;
  console.log(`usr:${username} pass:${password}`);
  
  if (username === "read_password" && password === "security_isnt_what_i_want") {
    res.statusCode = 200;
    res.setHeader("Content-Type", "text/plain");
    res.end("Login successful");
  } else {
    res.statusCode = 401;
    res.setHeader("Content-Type", "text/plain");
    res.end("Login failed");
  }
}

server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});

3. 可选:完善客户端错误处理

添加错误状态的监听,方便调试:

xhr.onreadystatechange = function () {
  if (this.readyState == 4) {
    if (this.status == 200) {
      console.log(this.responseText);
    } else {
      console.log(`登录失败,状态码:${this.status},响应:${this.responseText}`);
    }
  }
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 01:40:38