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

Node.js配置CORS方法及80端口EADDRINUSE错误解决方案

基于Koa框架的Node.js服务示例代码
'use strict';

const app          = require('koa')();
const jwt          = require('koa-jwt');
const bodyParser   = require('koa-bodyparser');
const send         = require('koa-send');
const serve        = require('koa-static');
const jsonwebtoken = require('jsonwebtoken');
const error        = require('./middleware/error-middleware.js');
const router       = require('koa-router')();

// 生产环境请勿使用该硬编码密钥
const secret = 'supersecret';

app.use(error());
app.use(bodyParser());
app.use(serve('dist'));
app.use(jwt({ secret }).unless({
    path: [/^(?!\/api\/)/]
}));

// 示例逻辑仅做固定账号密码校验
// 生产环境需对接数据库,校验哈希加密后的密码
router.post('/auth', function* () {
    const username = this.request.body.username;
    const password = this.request.body.password;

    if (username !== 'chuck' && password !== 'norris') {
        this.throw(401, 'Invalid username/password.');
    }

    const user = {
        username,
        email: 'chuck@norris.com',
        firstName: 'Chuck',
        lastName: 'Norris',
        roles: ['admin']
    };

    const token = jsonwebtoken.sign(user, secret, {
        issuer: 'localhost',
        audience: 'someaudience',
        expiresIn: '1d'
    });

    this.body = { token };
});

app.use(router.routes());

app.use(function* () {
    yield send(this, '/dist/index.html');
});

app.on('error', err => console.log(err));

app.listen(3000, () => console.log('example running on port 3000'));
相关技术问题解答

1. Node.js项目中CORS跨域请求的正确配置方法

Koa项目配置CORS推荐使用官方维护的@koa/cors中间件,配置步骤如下:

  • 第一步安装依赖:执行npm install @koa/cors --save
  • 第二步注册中间件:必须将cors中间件注册在所有业务路由、jwt校验、bodyParser等其他中间件之前,保证跨域响应头能正常添加到所有响应中。基础配置代码如下:
const cors = require('@koa/cors');
// 放在所有app.use的最前面
app.use(cors());
  • 按需自定义配置:如果有允许携带Cookie、限制允许跨域的源、自定义允许的请求头等需求,可以传入配置参数:
app.use(cors({
  origin: 'https://你的前端域名.com', // 不要写*,否则携带凭证的请求会失败
  credentials: true, // 允许跨域请求携带Cookie、Authorization头
  allowMethods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
  allowHeaders: ['Content-Type', 'Authorization']
}));
  • 额外注意事项:如果项目用了koa-jwt做鉴权,需要把OPTIONS预检请求加入jwt豁免路径,否则预检请求会因为不带token被拦截,导致跨域失败:
app.use(jwt({ secret }).unless({
    path: [/^(?!\/api\/)/],
    method: 'OPTIONS' // 放行所有OPTIONS预检请求
}));

如果不想引入第三方依赖,也可以手写中间件设置CORS相关响应头,本质就是给每个响应加上Access-Control-Allow-Origin、Access-Control-Allow-Methods等标准跨域头,同时单独处理OPTIONS方法的预检请求即可。

2. 80端口启动报listen EADDRINUSE错误的解决方案与原理

错误原因

EADDRINUSE是系统层面抛出的网络错误,含义是你要监听的本地端口已经被其他进程绑定占用。操作系统规则不允许同一时间同一个网络地址+端口被多个进程同时监听,只要有其他程序已经占了80端口,Node服务再启动绑定这个端口就会直接报错。
除此之外,Linux、macOS系统下1024以下的端口属于系统特权端口,普通用户账号没有直接监听的权限,就算端口没被占用,普通用户启动服务也会报权限错误。

解决方法

  • 排查并释放占用80端口的进程:
    • Windows系统执行命令netstat -ano | findstr :80,查到占用端口的进程PID后,执行taskkill /PID 查到的进程号 /F强制结束进程
    • macOS/Linux系统执行命令sudo lsof -i :80查到占用进程的PID,执行sudo kill -9 查到的进程号结束进程
  • 更安全的生产方案:不要直接用root权限启动Node服务监听80端口,而是让Node服务监听3000这类高位端口,通过Nginx反向代理或者系统端口转发规则,把80端口的入站流量转发到Node服务的端口上,既避免端口冲突,也降低服务运行的安全风险。
  • 开发环境直接换用3000、8080这类没有被占用的高位端口启动即可,不需要强行用80端口。

为什么浏览器访问互联网不受该问题影响

浏览器是作为网络客户端发起出站请求,根本不需要在本地监听80端口:
当你用浏览器访问外网网站时,系统会给浏览器分配一个1024以上的随机临时端口作为源端口,去连接远端服务器的80/443目标端口,整个过程本地没有任何进程绑定监听80端口,自然不会和Node服务监听本地80端口的操作产生冲突。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 05:55:05