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包(更简洁)
- 安装cors包:
npm install cors
- 修改后端代码(改用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
相关产品推荐
相关产品推荐

