NodeJS上传视频至Blogger遇阻:视频数据未传输问题求助
Blogger视频上传问题:bytesTransferred始终为0
我尝试用以下NodeJS代码向Blogger上传视频,请求能获取响应,但视频数据无法传输,返回的响应中bytesTransferred字段显示为0,说明视频数据未被传输。
我的NodeJS代码
const axios = require('axios'); const fs = require('fs'); const path = require('path'); const videoPath = '/Downloads/11H3Bepq6Hx_seEhq2iO7OSW1zC01PnKo.mp4'; const videoStream = fs.createReadStream(videoPath); let data = '{"protocolVersion":"0.8","createSessionRequest":{"fields":[{"external":{"name":"file","filename":"11H3Bepq6Hx_seEhq2iO7OSW1zC01PnKo.mp4","put":{},"size":1018020}},{"inlined":{"name":"title","content":"11H3Bepq6Hx_seEhq2iO7OSW1zC01PnKo.mp4","contentType":"text/plain"}},{"inlined":{"name":"addtime","content":"1726417159033","contentType":"text/plain"}},{"inlined":{"name":"onepick_version","content":"v2","contentType":"text/plain"}},{"inlined":{"name":"onepick_host_id","content":"10","contentType":"text/plain"}},{"inlined":{"name":"onepick_host_usecase","content":"RichEditor","contentType":"text/plain"}},{"inlined":{"name":"tos","content":"true","contentType":"text/plain"}},{"inlined":{"name":"blogID","content":"add-your-own-id-here","contentType":"text/plain"}},{"inlined":{"name":"postID","content":"add-your-own-id-here","contentType":"text/plain"}}]}}'; let config = { method: 'post', url: 'https://docs.google.com/upload/blogger/resumable?authuser=0&opi=98421741', headers: { 'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8', 'Accept': '*/*', 'Sec-Fetch-Site': 'same-origin', 'Accept-Language': 'en-IN,en-GB;q=0.9,en;q=0.8', 'Accept-Encoding': 'gzip, deflate, br', 'Sec-Fetch-Mode': 'cors', 'Host': 'docs.google.com', 'Origin': 'https://docs.google.com', 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.6 Safari/605.1.15', 'Referer': 'https://docs.google.com/', 'Content-Length': '860', 'Connection': 'keep-alive', 'Sec-Fetch-Dest': 'empty', 'Cookie': '', 'X-Goog-Upload-Header-Content-Type': 'video/mp4', 'X-Goog-Upload-Header-Content-Length': '1018020', 'X-Client-Pctx': 'CgcSBWjtl_cu', 'X-Goog-Upload-Protocol': 'resumable', 'X-Goog-Upload-Command': 'start' }, data: data }; axios.request(config) .then((response) => { console.log(JSON.stringify(response.data)); const boundary = '----WebKitFormBoundary7MA4YWxkTrZu0gW'; const body = `--${boundary}\r\n` + `Content-Disposition: form-data; name="metadata"\r\n\r\n` + `${data}\r\n` + `--${boundary}\r\n` + `Content-Disposition: form-data; name="Filedata"; filename="${path.basename(videoPath)}"\r\n` + `Content-Type: video/mp4\r\n` + `Content-Transfer-Encoding: binary\r\n\r\n` + `${fs.readFileSync(videoPath, { encoding: 'binary' })}\r\n` + `--${boundary}--`; let config = { method: 'post', url: `https://docs.google.com/upload/blogger/resumable?authuser=0&opi=98421741&upload_id=${response.data['sessionStatus']['upload_id']}&upload_protocol=resumable`, headers: { 'Content-Type': `multipart/related; boundary=${boundary}`, 'Accept': '*/*', 'Sec-Fetch-Site': 'same-origin', 'Accept-Language': 'en-IN,en-GB;q=0.9,en;q=0.8', 'Accept-Encoding': 'gzip, deflate, br', 'Sec-Fetch-Mode': 'cors', 'Host': 'docs.google.com', 'Origin': 'https://docs.google.com', 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.6 Safari/605.1.15', 'Referer': 'https://docs.google.com/', 'Content-Length': '1018020', 'Connection': 'keep-alive', 'Sec-Fetch-Dest': 'empty', 'Cookie': '', "X-Goog-Upload-Protocol": "multipart", }, "cache": "default", "credentials": "include", "mode": "cors", "redirect": "follow", "referrer": "https://docs.google.com/", "referrerPolicy": "origin", data: body }; axios.request(config) .then((response) => { console.log(JSON.stringify(response.data)); }) .catch((error) => { console.log(error); }); }) .catch((error) => { console.log(error); });
Blogger返回的异常响应
{"sessionStatus":{"state":"FINALIZED","externalFieldTransfers":[{"name":"file","status":"COMPLETED","bytesTransferred":0,"bytesTotal":1018020,"putInfo":{"url":"https://docs.google.com/upload/blogger/resumable?authuser=0&opi=98421741&upload_protocol=resumable&upload_id=AD-8ljsco6WMZdutraflzfW1AtmJ1k5OYO2PudwjgaYof8PaCSqRn5kqZofxDnlNtVlaig95-jM&file_id=000"},"content_type":"video/mp4"}],"additionalInfo":{"uploader_service.GoogleRupioAdditionalInfo":{"completionInfo":{"status":"SUCCESS"}},"upload_id":"AD-8ljsco6WMZdutraflzfW1AtmJ1k5OYO2PudwjgaYof8PaCSqRn5kqZofxDnlNtVlaig95-jM"}}
可以看到bytesTransferred显示为0,说明视频数据未被传输。
浏览器上传的正常响应
{"sessionStatus":{"state":"FINALIZED","externalFieldTransfers":[{"name":"file","status":"COMPLETED","bytesTransferred":1018020,"bytesTotal":1018020,"putInfo":{"url":"https://docs.google.com/upload/blogger/resumable?authuser=0&opi=98421741&upload_id=AD-8ljvGMD4Mg6k6oSxW74UCa0gsZKJt3grXpwNS6UFtbCnu0D-HyPXF5_B_Krr1aJ-mZQjJ3jcicPLGUSAARAl4TJdDosvQiwltu-Xd139T0aI0&file_id=000"},"content_type":"video/mp4"}],"additionalInfo":{"uploader_service.GoogleRupioAdditionalInfo":{"completionInfo":{"status":"SUCCESS","customerSpecificInfo":{"contentId": "ed34314396d57090"}}}},"upload_id":"AD-8ljvGMD4Mg6k6oSxW74UCa0gsZKJt3grXpwNS6UFtbCnu0D-HyPXF5_B_Krr1aJ-mZQjJ3jcicPLGUSAARAl4TJdDosvQiwltu-Xd139T0aI0"}}
此处bytesTransferred与bytesTotal数值一致,均为1018020。
找到的参考代码
h.Xc = function() { var a = yd(this.Ca); this.V.length != null && (a["Content-Length"] = this.V.length); a = fac(a); a["X-Goog-Upload-Protocol"] = "multipart"; a["Content-Type"] = "multipart/related; boundary=" + this.U; this.H = "Transferring"; this.N = new DZ; this.O.te(); this.O.listen(this.N, "progress", this.pda); this.O.listen(this.N, "complete", this.oda); var b = this.N, c = b.send, d = this.Ia, e = this.Ha, f = "--" + this.U + '\r\nContent-Disposition: form-data; name="metadata"\r\n\r\n' + (this.Ga + "\r\n--") + this.U + '\r\nContent-Disposition: form-data; name="Filedata"\r\nContent-Transfer-Encoding: ' + (this.La + "\r\n\r\n") + this.V + "\r\n--" + this.U + "--\r\n"; this.wa = f.length - this.V.length; c.call(b, d, e, f, a) };
测试时需先登录Blogger获取Cookie值,同时将代码中data变量里的add-your-own-id-here替换为实际的博客ID和文章ID。
内容的提问来源于stack exchange,提问作者Karan Kankaria
相关产品推荐
相关产品推荐

