从外部 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 保存在服务器上 [重复]的主要内容,如果未能解决你的问题,请参考以下文章
angular 2组件无法从外部css皮肤加载相对背景图像url