好吧,既然没人回答,我自己折腾了一下午解决了问题。 这里面坑真多,为了能抓 node server 包就花了我好长时间。 我前后抓了 request 和 node-fetch 的包,进行报文头部的分析,因为我猜测,肯定是报文某个字段请求微信服务器它不认可。 request post host: api.weixin.qq.com content-type: multipart/form-data; boundary=--------------------------432155727223273682777525 content-length: 45303 Connection: close ----------------------------432155727223273682777525 Content-Disposition: form-data; name="media"; filename="2.jpg" Content-Type: image/jpeg ...DATA... ----------------------------432155727223273682777525-- node-fetch post Host: api.weixin.qq.com Content-Type: multipart/form-data;boundary=--------------------------297137759555768400521474 Accept: */* User-Agent: node-fetch/1.0 (+https://github.com/bitinn/node-fetch) Accept-Encoding: gzip,deflate Connection: close Transfer-Encoding: chunked ----------------------------297137759555768400521474 Content-Disposition: form-data; name="media"; filename="2.jpg" Content-Type: image/jpeg ...DATA... ----------------------------297137759555768400521474-- 前后对面他们的请求报文字段几乎一致,不一致的 Accept User-Agent Accept-Encoding Transfer-Encoding,这几个都是无关紧要的,一般来说服务器不会对他们做出逻辑回应。 那么问题应该就出在 node-fetch 没有自动设置 content-length 了,猜测微信服务器应该对这个字段做了判断校验,比如媒体文件大小限制,发现没法判断,则返回了错误。 问题找到了,那就容易解决了(虽然也不容易还是有何种坑) 为什么 node-fetch 不会自动设置 content-length 字段呢,不应该啊,于是我扒了下官方文档看到这个 [图片] 我就是以流文件上传的,所以他没法设置这个字段,那我就自己设置他好了 上代码 const fetch = require('node-fetch') const fs = require('fs') const FormData = require('form-data') const media = fs.createReadStream('foo.jpg') // 获取文件的信息 const stats = fs.statSync('foo.jpg') const formData = new FormData() // 在这里传递文件的长度 formData.append('media', media, { knownLength: stats.size }) const response = await fetch(url, { method: 'POST', headers:{ // 千万不要在这里传 'Content-Length',因为实际上你的报文长度和文件大小并不一致,之前我设置了 formData 的大小,这里就能自动生成真实报文长度了 } body: formData }) if (!response.ok) { console.log(response.status) reject('error') throw new Error('Upload material failed') }else{ console.log(await response.json()) }
公众号开发 fetch 调用【上传图文消息内的图片获取URL】接口时,返回 412 错误?我用的 NodeJS 开发的,在用 node-fetch 上传图片是返回的 HTTP STATUS 是 412 错误,我很确定我的代码是正确的,并且发现了有类似相同的问题 这是另一个问题的链接 https://developers.weixin.qq.com/community/develop/doc/00000ef32dc64883d9d93f31f56800 但我对此问题的回答并不满意,因为 request 库早在很多年前就弃用了,原作者推荐用 node-fetch 我觉得不应该用弃用的库应对目前业务,可无奈所搜了一堆现有的微信公众号开发的列子,用的都是 request 希望社区有大神给予解答,附上我的代码 const fetch = require('node-fetch') const fs = require('fs') const FormData = require('form-data') const media = fs.createReadStream('foo.jpg') const formData = new FormData() formData.append('media', media) const response = await fetch(url, { method: 'POST', body: formData }) if (!response.ok) { console.log(response.status) reject('error') throw new Error('Upload material failed') } // 412 // Error: Upload material failed
2022-10-23