如何下载文件名不以扩展名结尾的图像?

时间:2018-07-23 09:11:53

标签: javascript node.js

如果右键单击Github和open image in new tab上的任何个人资料图片,您会发现它没有以扩展名结尾

例如,这是github上用户的实际图像:

https://avatars0.githubusercontent.com/u/170270?s=60&v=4

目标

我正尝试使用request模块向我的node.js应用添加图像保存功能:

// A proper image link (e.g. *.jpg)
let fileUrl_1 = "https://cdn.pixabay.com/photo/2016/06/20/03/15/pier-1467984_1280.jpg"

// Semi proper image link (e.g. *.jpeg?query)
let fileUrl_2 = "https://images.pexels.com/photos/371633/pexels-photo-371633.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260"

// Not a proper image link (e.g. filename[no extension]?query)
let fileUrl_3 = "https://avatars0.githubusercontent.com/u/170270?s=60&v=4"

let parsedPath = pathModule.parse(fileUrl_1)
let fileName = parsedPath.base
let destinationPath = `C:\\test\\${fileName}`

let request = require("request")
request
  .get(fileUrl_1)
  .on('error', function(err) {
    console.log(err)
  })
  .pipe(fs.createWriteStream(destinationPath))

问题

当我尝试使用fileUrl_1之类的正常路径下载图像时,它可以正常工作,但是,如果我尝试下载上述的fileUrl_2fileUrl_3之类的图像,则会出现错误:

ENOENT: no such file or directory, open 'C:\test\170270?s=60&v=4'

但是,如果您只是在任何浏览器中的“问题”图像上right-click / save image as,则将获得一个save as对话框窗口,并且可以将该图像另存为{ {1}}

问题

如何像170270.jpg对话框窗口那样使用node.js下载任何图像(即使图像没有以适当的扩展名结尾也要检索图像)?

2 个答案:

答案 0 :(得分:6)

完全取决于您要选择的目标文件名。检索图像没有问题-唯一的问题是您尝试使用无效的文件名进行保存。

服务器响应中可能包含Content-Disposition header,其中可能包含建议的默认文件名。

  

文件名始终是可选的,并且不能被应用程序盲目使用:路径信息应删除,并应转换为服务器文件系统规则。

它还应包含一个Content-Type header,您可以从中导出文件扩展名,但是此标头可能不正确。

  

在某些情况下,浏览器将执行MIME嗅探,并且不一定遵循此标头的值

或者您可以“嗅探”响应正文的前几个字节,然后检查一个已知的幻数以指示文件类型。

答案 1 :(得分:2)

pathModule.parse用于解析文件路径,而不是URL。

其中没有提供有效文件名的示例是其中带有?的示例。

改为使用URL解析器。

const url = require('url');

var fileName = url
  .parse(
    'https://images.pexels.com/photos/371633/pexels-photo-371633.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260'
  )
  .pathname.match(/\/([^\/]*)$/)[1];

console.log(fileName);