NodeJS使用http.request或Axios发送POST请求时出现EPROTO错误的排查求助
解决Node.js本地跨服务请求的EPROTO错误与请求体为空问题
先来说说你遇到的两个核心问题:EPROTO SSL版本错误和接收端获取到的请求体属性全为null,咱们一个个来拆解解决。
一、先搞定EPROTO错误
你看到的Error: write EPROTO ... ssl3_get_record:wrong version number这个错误,本质是请求协议和服务器运行的协议不匹配。比如你用http.request发HTTP请求,但目标服务器是HTTPS服务;或者反过来,你默认走了HTTPS,但服务器是HTTP的。
看你的代码,不管是http.request还是Axios调用,都有个小问题:
http.request的options里没显式指定protocol,默认是http:,但如果你的目标服务器(3000端口)是用HTTPS启动的,就会触发SSL版本不匹配错误。- Axios的请求地址写的是
localhost:3000/v1/orders/create,没加协议前缀,Axios可能会默认继承当前服务的协议(如果你的发送端是HTTPS服务),导致用HTTPS请求HTTP服务器。
解决办法:
- 给请求显式指定正确的协议:
- 如果目标服务器是HTTP,
http.request的options里加protocol: 'http:',Axios的地址写成http://localhost:3000/v1/orders/create - 如果目标服务器是HTTPS,
http.request的options里加protocol: 'https:',Axios的地址写成https://localhost:3000/v1/orders/create
- 如果目标服务器是HTTP,
二、解决请求体属性全为null的问题
接收端能收到请求但属性都是null,主要有两个原因:
1. 发送端请求头拼写错误
你在http.request的options里写的是header,但正确的属性名应该是**headers**(复数)!少了个s,导致服务器没收到Content-Type: application/json的头,自然不会把请求体解析成JSON对象,所以拿到的都是默认null。
修正后的options应该是:
const options = { host: 'localhost', port: 3000, path: '/create', method: 'POST', headers: { // 这里是headers,不是header 'Content-Type':'application/json' } }
2. 接收端没有正确解析JSON请求体
即使发送端头对了,接收端如果没配置JSON解析中间件,也没法自动把请求体转成对象。比如如果接收端是Express框架,需要加上:
const express = require('express'); const app = express(); app.use(express.json()); // 关键:解析JSON请求体
如果是原生Node.js的HTTP服务器,需要手动监听data和end事件来拼接请求体:
const server = http.createServer((req, res) => { let body = ''; req.on('data', chunk => { body += chunk.toString(); }); req.on('end', () => { const parsedBody = JSON.parse(body); // 手动解析JSON console.log(parsedBody); // 现在就能拿到正确的属性值了 res.end('OK'); }); });
额外注意:发送请求时的细节
- 用
http.request的时候,最好加上错误监听,避免未处理的error事件崩溃:
req = http.request(options, (res) => { console.log(res.statusCode); let resBody = ''; res.on('data', chunk => resBody += chunk); res.on('end', () => console.log(JSON.parse(resBody))); }); // 加上error监听 req.on('error', (err) => { console.error('请求出错:', err); }); req.write(stringifiedBody); req.end();
- 你代码里的
resource.Inquiries.create;少了括号,应该是resource.Inquiries.create();才会执行请求。
把这些点都修正后,应该就能正常发送请求并获取到正确的请求体数据了。
内容的提问来源于stack exchange,提问作者darkshadowtrail
相关产品推荐
相关产品推荐

