从外部 URL 下载图像,使用 JavaScript 和 ExpressJs 保存在服务器上 [重复]

Posted

技术标签:

【中文标题】从外部 URL 下载图像,使用 JavaScript 和 ExpressJs 保存在服务器上 [重复]【英文标题】:Downloading image from external URL, saving on server using JavaScript and ExpressJs [duplicate] 【发布时间】:2020-03-25 03:05:18 【问题描述】:

我有一个挣扎。假设我得到如下所示的 JSON 响应:


    "items": [
        "title": "test",
        "url": "http://urlToSomeImage.png",
        "description": "desc"
    , 
        "title": "test",
        "url": "http://urlToSomeImage.png",
        "description": "desc"
    ]

现在,如果您通过浏览器访问这些 URL,所有这些 URL 都会显示图片。 我想下载一张图片并将其存储在我的服务器上的某个静态路径+基于名称的某个动态路径。带路径的那部分很简单,但是从外部 URL 实际下载文件并将其放在我的服务器上的路径,因为我不知道从什么开始。

我正在使用 ExpressJS 和 vanilla javasript(在 nodeJs 环境中运行)。 我需要什么?从什么开始?

【问题讨论】:

这不是有效的 JSON 对不起,我编辑了。即便如此,实际上给出一些建议而不是你写的内容会很好。 “即便如此”...我从你给我的开始。当问题一开始就根本错误时,我的工作不是给你讲义,而且我认为你要求我在此基础上给你建议是不礼貌的。 【参考方案1】:

如果您想将图像存储在服务器上,那么您的服务器应该下载文件并存储它。

下面是一个简单的示例,说明我将如何做到这一点:

const path = require('path')
const fs = require('fs')
const URL = require('url').URL
const http = require('http')
const https = require('https')

// Define a function to download images from a passed array of URL's.
const downloadImages = (arr, folderpath = '') => 
  // - Create a new array of `Promise`s from the passed array, using `Array.map`
  //   and pass that new array to `Promise.all` so they are all waited for
  //   in-parallel.
  // - Each `Promise` in this new array resolves when the data specified in
  //   the passed array `item.URL` is downloaded and saved to a file with the
  //   appropriate name.
  return Promise.all(arr.map(item => 
    // For each item in the passed array...

    // Create and return a Promise which:
    return new Promise((resolve, reject) => 
      // Creates a `WriteStream` to a local file on path:
      // '[root directory path]/[folderpath]/[item.title].[extension]'
      const extension = path.extname(item.url)
      const filepath = `$path.dirname(process.mainModule.filename)$folderpath/$item.title$extension`
      const writeStream = fs.createWriteStream(filepath)

      // Reject if there's an error acquiring or writing to the `WriteStream`.
      writeStream.on('error', reject)

      // - Ensure we use the appropriate http module for downloading the file.
      // - If the `item.url` is HTTPS we use the `https` module, otherwise we
      //   use the `http` module.
      const protocol = new URL(item.url).protocol
      const requester = protocol === 'https:' ? https : http

      // Get a stream to the data on the URL.
      requester
        .get(item.url, res => 
          // Reject the Promise if the HTTP status code is not 200.
          if (res.statusCode !== 200) 
            return reject(`$item.url failed, HTTP status: $res.statusCode`)
          

          // Otherwise pass the stream to the `WriteStream` so it can be written
          // to the local file.
          res.pipe(writeStream)
          // When it's done, resolve the Promise.
          writeStream.on('finish', resolve)
        )
        .on('error', reject) // Also reject if there's a generic request error.
    )
  ))


// Test the function in an async IIFE since we are going to use await.
;(async () => 
  try 
    // `downloadImages` returns a Promise so we need to await it.
    await downloadImages([
      
        title: 'lenna-color',
        url: 'https://upload.wikimedia.org/wikipedia/en/7/7d/Lenna_%28test_image%29.png'
      ,
      
        title: 'lenna-grayscale',
        url: 'https://www.ece.rice.edu/~wakin/images/lenaTest3.jpg'
      
    ])
    console.log('done')
   catch (err) 
    console.error(err)
  
)()

你关心的部分是我上面定义的downloadImages(arr, folderpath)函数。

如果要将图像保存到根目录,可以这样调用:

await downloadImages([
  
    title: 'lenna-color',
    url: 'https://upload.wikimedia.org/wikipedia/en/7/7d/Lenna_%28test_image%29.png'
  ,
  
    title: 'lenna-grayscale',
    url: 'https://www.ece.rice.edu/~wakin/images/lenaTest3.jpg'
  
])

或保存在根目录中名为“images”的文件夹中:

await downloadImages([
  
    title: 'lenna-color',
    url: 'https://upload.wikimedia.org/wikipedia/en/7/7d/Lenna_%28test_image%29.png'
  ,
  
    title: 'lenna-grayscale',
    url: 'https://www.ece.rice.edu/~wakin/images/lenaTest3.jpg'
  
], '/images')

【讨论】:

这看起来很有帮助! Thx,我稍后会试试这个。我在哪里准确指定在我的服务器上保存文件的位置? fs.CreateWriteStream(filepath)。第一个参数采用文件路径。 你太棒了!非常感谢。

以上是关于从外部 URL 下载图像,使用 JavaScript 和 ExpressJs 保存在服务器上 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

从 JSON url 下载图像不起作用。 [关闭]

angular 2组件无法从外部css皮肤加载相对背景图像url

JavaScript - 将图像从 URL 保存到本地机器特定路径?

使用spring boot从外部url下载文件

Kivy 无法从外部 URL 加载图像

如何使用外部图像 url 打印 iframe 内容