使用jQuery.ajax调用Facebook Graph API返回400 Bad Request错误
问题原因
返回400的核心原因是请求体格式和你声明的Content-Type不匹配:
你手动设置了请求头contentType: "application/json",但直接把原生JS对象传给data参数时,jQuery默认会把对象转成key1=val1&key2=val2格式的表单编码字符串,根本不会输出标准JSON结构。Facebook的消息接口收到和声明格式不符的请求体,就会直接返回400错误。
Postman能跑通是因为你在Postman里选了raw/JSON模式传参,实际发出去的请求体是合法JSON字符串,和你当前jQuery代码发出的请求内容格式完全不一样。
修复方案
把传给data的参数用JSON.stringify()手动序列化为标准JSON字符串即可,修正后的代码如下:
$.ajax({ method: "POST", // 注意把<MY_ACCESS_TOKEN>替换成你自己的真实Page Access Token url: 'https://graph.facebook.com/v14.0/me/messages?access_token=<MY_ACCESS_TOKEN>', // 序列化JS对象为合法JSON字符串 data: JSON.stringify({ "recipient": { "id": psid // 提前确认psid是有效、对应当前主页的用户PSID }, "message": { "text": "hello, world!" } }), contentType: "application/json", success: function (response) { console.log('消息发送成功', response) }, // 建议加上错误回调,后续出问题可以直接打印接口返回的错误信息快速定位 error: function(xhr) { console.log('请求报错', xhr.responseJSON) } })
可选替代方案
如果你不想手动做JSON序列化,可以删掉contentType: "application/json"这行配置,jQuery会默认使用application/x-www-form-urlencoded格式传参,Facebook的消息接口同样支持这种格式的请求,不过官方文档推荐优先使用JSON格式传参。
额外排查项
如果改完还是报错,依次检查以下几点:
- 你使用的Access Token是对应主页的有效Token,已经申请到
pages_messaging权限 - 传入的psid是用户和你当前主页机器人对话生成的有效PSID,不是其他主页、或者已过期的用户标识
- 你调用接口的环境符合Facebook Messenger接口的调用规则,没有触发接口的频率限制、权限限制
内容的提问来源于stack exchange,提问作者Lorenzo Yu
相关产品推荐
相关产品推荐

