代码之家  ›  专栏  ›  技术社区  ›  Un1

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

  •  1
  • Un1  · 技术社区  · 6 年前

    如果右键单击Github上的任何配置文件图像 open image in new tab 你会发现它不会以一个扩展名结束

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

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

    目标

    我正在尝试使用 request 模块

    // 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_2 fileUrl_3 如上所示,我得到一个错误:

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

    但是,如果你只是 right-click / save image as 在任何浏览器中的“有问题”图像上,您将得到 save as 对话框窗口,可以将此图像另存为 170270.jpg

    问题

    如何使用node.js下载任何图像,如 另存为 对话框窗口是否(即使图像没有以正确的扩展名结束,也要重新获取图像)?

    2 回复  |  直到 6 年前
        1
  •  6
  •   OrangeDog    6 年前

    完全由您根据需要选择目标文件名。检索图像没有问题-唯一的问题是试图用无效的文件名保存图像。

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

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

    它还应该包括 Content-Type header 从中可以派生文件扩展名,但是此头可能不正确。

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

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

        2
  •  2
  •   Quentin    6 年前

    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);