当前位置: 首页 > 后端技术 > Node.js

【复制攻城狮日志】Node.jshttp下载图片失败

时间:2023-04-03 20:20:58 Node.js

创建于2019-4-522:24:33byhuqi更新于2019-4-523:23:56byhuqi↑开始图片,故事是一切关于编造↑从回答一个知不知道的问题开始。有时候,我觉得自己在签自己的知否——我想的就是我想的?一直以来,我对前端技术的无知导致我遇到问题总是一边倒的。比如这次,我翻车了。技术水平就那样,然后还想帮别人解答,这不是误导孩子吗?昨天回答的问题是关于node.js的http方法的。根据Url获取网络图片,写入本地文件夹。这个需求我之前也玩过,不过我用的是Copy&Paste的代码,并没有详细研究源码,我只知道使用了request模块,但是这次小伙伴没有依赖任何第三方模块,只是使用了内置的http模块。他遇到的问题如上图所示。一张图片下载不成功,无法正常显示。具体问题参见@夜鹰:使用Node.js读取远程图片文件并写入本地?通过内置http模块下载图片源码导入内置http模块发起请求获取文件导入内置fs模块写入文件consthttp=require('http')constfs=require('fs')consturlArr=['http://img.zcool.cn/community/01e505554437be0000019ae95582a2.jpg@900w_1l_2o_100sh.jpg','http://static.pig66.com/uploadfile/2017/1102/20171102095531217.png',]urlArr.forEach(url=url>{)})functiongetImg(url,name){http.get(url,{encoding:null},res=>{letimg=[]letsize=0//用[.]符号分割图片的url,取最后一项为格式后缀const_arr=url.split('.')constformat=_arr[_arr.length-1]//如果没有图片名称传入,使用随机数const_name=name?name:'image-'+Math.floor(Number(newDate())*Number(Math.random()))res.on('data',chunk=>{img.push(chunk)size+=chunk.length})res.on('end',()=>{//合并缓冲区constbuffer=Buffer.concat(img,size)fs.writeFileSync(`img/${_name}.${format}`,buffer,(err)=>{if(err){returnconsole.error(err);}console.log("数据写入成功!");})})})}对于我来说,一开始我以为是因为文件太大,因为我看到Buffer数据被打断了,直接通过output结束了。然后试了一下1M左右的图片,完全可以下载成功。然而,我被打了脸。接下来草草下结论,给博主一个使用第三方模块请求实现相同功能的实现(见历史版本:共编辑4次)。真相纠缠是怎样的?另一位回答者@啊嘿已经给出了相当明确的回答!“罪魁祸首”——301重定向301重定向(页面被永久删除)是一项非常重要的“自动重定向”技术。最可行的方法之一是URL重定向。当用户或搜索引擎向网络服务器发送浏览请求时,服务器返回的HTTP数据流头部中的状态码之一表示该网页被永久转移到另一个地址。打开图片链接:http://www.pig66.com/uploadfi...,通过查看Network可以清楚的看到源图片有301重定向。通过在源码中加入日志输出,我们也可以清楚的看到301状态码。既然已经找到了问题的根源,那么就针对症状写一个bug。如果是301,则获取请求返回的真实地址,重新发起请求。const{statusCode}=resif(statusCode===301){consturl=res.headers['location']returngetImg(url)}修改代码:consthttp=require('http')constfs=require('fs')consturlArr=['http://img.zcool.cn/community/01e505554437be0000019ae95582a2.jpg@900w_1l_2o_100sh.jpg','http://static.pig66.com/uploadfile/2017/1102/20171102095531217.png',]urlArr.forEach(url=>{getImg(url)})functiongetImg(url,name){http.get(url,{encoding:null},res=>{const{statusCode}=res控制台。log(statusCode)if(statusCode===301){consturl=res.headers['location']returngetImg(url)}letimg=[]letsize=0//用[.]分隔图片地址symbol,取最后一项,即格式后缀const_arr=url.split('.')constformat=_arr[_arr.length-1]//如果没有传入图片名,则使用随机数const_name=name?name:'image-'+Math.floor(Number(newDate())*Numberr(Math.random()))res.on('data',chunk=>{img.push(chunk)size+=chunk.length})res.on('end',()=>{//合并缓冲区constbuffer=Buffer.concat(img,size)fs.writeFileSync(`img/${_name}.${format}`,buffer,(err)=>{if(err){returnconsole.error(err);}console.log("数据写入成功!");})})})}成功拿到图片,可以直观感受到301重定向后又发起了一次请求。写了两个简单的页面,发现什么也做不了!想想我,还是那么热心的帮人答题。真是误会了孩子,害了别人。我想通过这次经历深刻反省自己,向所有被我欺骗的人表示深深的歉意。同时也希望大家不吝赐教,多多指教!最后祝@jsliang生日快乐!写在生日,一年前端辛苦