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

HTML中AJAX跨端口/服务器POST请求始终失败的求助

跨端口AJAX POST请求失败的解决思路

问题场景

HTML页面通过AJAX POST方法向Node.js搭建的8000端口服务器发送JSON数据时请求失败,但将HTML部署在同一端口服务器上时请求正常,需要实现跨端口/跨服务器的POST请求。

前端POST代码

$.post('http://localhost:8000', message).done(function(received) {
  $('#output').text('You chose ' + received.value + ' out of ' + received.maxValue)
}).fail(function () {
  $('#output').text('Failed')
})

后端Node.js代码

var http = require('http'),
  fs = require('fs'),
  path = require('path')

var PORT = 8000

fs.readFile(path.resolve(__dirname, "index.html"), function(err, html) {
  if (err) {
    throw err;
  }
  http.createServer(function(request, response) {
    if (request.url == '/home') {
      response.writeHeader(200, {
        "Content-Type": "text/html"
      });
      response.write(html);
      response.end();
    }
    if (request.method == 'POST') {
      console.log('POST2')
      var body = ''
      request.on('data', function(data) {
        body += data
      });
      request.on('end', function() {
        try {
          var post = JSON.parse(body);
          console.log(post);
          response.writeHead(200, {
            'Content-Type': 'application/json'
          });
          response.write(JSON.stringify(post))
          response.end();
          return;
        } catch (err) {
          var post = JSON.parse(body);
          response.writeHead(200, {
            'Content-Type': 'application/json'
          });
          response.write(body);
          response.end();
          return;
        }
      });
    }
  }).listen(PORT);
});
console.log('Node.js web server at port ' + PORT + ' is running..')

核心原因

浏览器的同源策略限制:跨端口属于不同源(协议、域名、端口三者任一不同即为跨域),浏览器会先发OPTIONS预检请求验证服务器是否允许跨域,但当前后端代码未处理OPTIONS请求,也未返回CORS相关响应头,导致请求被拦截。

解决方法

方法一:手动添加CORS响应头并处理OPTIONS请求

修改后端代码,在所有响应中添加CORS允许头,并专门处理OPTIONS预检请求:

var http = require('http'),
  fs = require('fs'),
  path = require('path')

var PORT = 8000

fs.readFile(path.resolve(__dirname, "index.html"), function(err, html) {
  if (err) {
    throw err;
  }
  http.createServer(function(request, response) {
    // 添加上CORS允许头
    response.setHeader('Access-Control-Allow-Origin', '*'); // 允许所有源,生产环境建议指定具体域名
    response.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
    response.setHeader('Access-Control-Allow-Headers', 'Content-Type');

    // 处理OPTIONS预检请求
    if (request.method === 'OPTIONS') {
      response.writeHead(200);
      response.end();
      return;
    }

    if (request.url == '/home') {
      response.writeHeader(200, {
        "Content-Type": "text/html"
      });
      response.write(html);
      response.end();
    }
    if (request.method == 'POST') {
      console.log('POST2')
      var body = ''
      request.on('data', function(data) {
        body += data
      });
      request.on('end', function() {
        try {
          var post = JSON.parse(body);
          console.log(post);
          response.writeHead(200, {
            'Content-Type': 'application/json'
          });
          response.write(JSON.stringify(post))
          response.end();
          return;
        } catch (err) {
          // 修复原代码try-catch逻辑错误,返回合法错误响应
          response.writeHead(400, {
            'Content-Type': 'application/json'
          });
          response.write(JSON.stringify({error: 'Invalid JSON format'}));
          response.end();
          return;
        }
      });
    }
  }).listen(PORT);
});
console.log('Node.js web server at port ' + PORT + ' is running..')

方法二:使用cors npm包(更简洁)

  1. 安装cors包:
npm install cors
  1. 修改后端代码(改用Express框架简化开发):
const express = require('express');
const cors = require('cors');
const fs = require('fs');
const path = require('path');

const app = express();
const PORT = 8000;

// 启用CORS
app.use(cors());
// 自动解析JSON请求体
app.use(express.json());

// 处理/home路由返回HTML
app.get('/home', (req, res) => {
  fs.readFile(path.resolve(__dirname, "index.html"), (err, html) => {
    if (err) throw err;
    res.setHeader('Content-Type', 'text/html');
    res.send(html);
  });
});

// 处理POST请求
app.post('/', (req, res) => {
  console.log(req.body);
  res.json(req.body);
});

app.listen(PORT, () => {
  console.log(`Node.js web server at port ${PORT} is running..`);
});

前端补充优化

jQuery的$.post默认Content-Type为application/x-www-form-urlencoded,如果后端期望接收JSON,建议显式设置请求头确保格式匹配:

$.ajax({
  url: 'http://localhost:8000',
  type: 'POST',
  data: JSON.stringify(message),
  contentType: 'application/json',
  success: function(received) {
    $('#output').text('You chose ' + received.value + ' out of ' + received.maxValue)
  },
  error: function() {
    $('#output').text('Failed')
  }
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 22:16:16