如何用Node.js发送VoIP推送通知?Curl可行但Node.js遇405错误
Fixing 405 Error When Sending VoIP Push Notifications via Node.js HTTP/2
我来帮你搞定这个405错误——这个状态码说明APNs服务器不接受你当前的请求方法,对比你能正常工作的Curl命令,咱们来拆解问题:
问题根源
- HTTP/2请求格式用错了:你沿用了传统
http模块的options写法(比如method、hostname、path),但HTTP/2模块需要用伪头(:method、:path)来指定请求方法和路径,不是放在options里。 - 漏掉了请求体:Curl里的
-d '{"aps":{"alert":"hello"}}'是把JSON数据作为POST请求体发送,但你的Node.js代码里req.end()是空的,这会让APNs认为这不是一个有效的POST请求。 - 多余配置干扰请求:
protocol、hostname这些属性在http2.connect之后完全不需要,反而会打乱请求格式。
修正后的代码
const http2 = require('http2'); const fs = require('fs'); exports.handler = async (event) => { const bundleID = 'com.swiswiswift.CharacterAlarm'; const deviceToken = 'ede0d5e78f771d5916345aa48bd098e86aeab40b5e7d985fb9c74586d1a5a681'; // 建立HTTP/2连接,记得加上https协议前缀 const client = http2.connect('https://api.push.apple.com'); // 构造HTTP/2标准请求头,包含伪头和APNs必填的topic const headers = { ':method': 'POST', ':path': `/3/device/${deviceToken}`, 'apns-topic': bundleID }; // 创建请求,把证书配置放在连接选项里 const req = client.request(headers, { cert: fs.readFileSync('chara.pem'), passphrase: "passphrase" }); req.setEncoding('utf8'); req.on('response', (headers, flags) => { console.log('Response headers:', headers); }); let data = ''; req.on('data', (d) => data += d); req.on('end', () => { console.log('Response body:', data); client.destroy(); // 请求完成后关闭连接 }); // 发送请求体,和Curl命令里的payload完全一致 req.end(JSON.stringify({ aps: { alert: "hello" } })); }; exports.handler('local-test');
关键修改说明
- 把请求方法和路径移到
headers里的:method和:path伪头,这是HTTP/2的标准格式 - 将证书配置放在
client.request的第二个参数(连接选项)中,而非原来的options对象 - 在
req.end()里传入JSON字符串作为请求体,和你Curl命令的payload保持一致 - 给
http2.connect的URL加上https://前缀,确保连接正常建立
运行修正后的代码,应该就能成功发送VoIP推送,不会再返回405错误了。
内容的提问来源于stack exchange,提问作者takoikatakotako
相关产品推荐
相关产品推荐

