如何在不使用第三方库的情况下使用Node.js下载文件?
我不需要什么特别的东西。我只想从给定的URL下载文件,然后将其保存到给定的目录。
如何在不使用第三方库的情况下使用Node.js下载文件?
我不需要什么特别的东西。我只想从给定的URL下载文件,然后将其保存到给定的目录。
当前回答
路径:img 类型:JPG 随机函数
function resim(url) {
var http = require("http");
var fs = require("fs");
var sayi = Math.floor(Math.random()*10000000000);
var uzanti = ".jpg";
var file = fs.createWriteStream("img/"+sayi+uzanti);
var request = http.get(url, function(response) {
response.pipe(file);
});
return sayi+uzanti;
}
其他回答
你好,我认为你可以使用child_process模块和curl命令。
const cp = require('child_process');
let download = async function(uri, filename){
let command = `curl -o ${filename} '${uri}'`;
let result = cp.execSync(command);
};
async function test() {
await download('http://zhangwenning.top/20181221001417.png', './20181221001417.png')
}
test()
另外,当你想下载较大、多个文件时,你可以使用集群模块来使用更多的cpu内核。
超时解决方案,防止内存泄漏:
下面的代码是基于Brandon Tilley的回答:
var http = require('http'),
fs = require('fs');
var request = http.get("http://example12345.com/yourfile.html", function(response) {
if (response.statusCode === 200) {
var file = fs.createWriteStream("copy.html");
response.pipe(file);
}
// Add timeout.
request.setTimeout(12000, function () {
request.abort();
});
});
当您得到一个错误时,不要创建文件,并倾向于使用超时在X秒后关闭您的请求。
使用promise下载,它解析可读流。添加额外的逻辑来处理重定向。
var http = require('http');
var promise = require('bluebird');
var url = require('url');
var fs = require('fs');
var assert = require('assert');
function download(option) {
assert(option);
if (typeof option == 'string') {
option = url.parse(option);
}
return new promise(function(resolve, reject) {
var req = http.request(option, function(res) {
if (res.statusCode == 200) {
resolve(res);
} else {
if (res.statusCode === 301 && res.headers.location) {
resolve(download(res.headers.location));
} else {
reject(res.statusCode);
}
}
})
.on('error', function(e) {
reject(e);
})
.end();
});
}
download('http://localhost:8080/redirect')
.then(function(stream) {
try {
var writeStream = fs.createWriteStream('holyhigh.jpg');
stream.pipe(writeStream);
} catch(e) {
console.error(e);
}
});
使用http2模块
我看到了使用http、https和request模块的答案。我想添加一个使用另一个本地NodeJS模块,支持http或https协议:
解决方案
我已经参考了官方的NodeJS API,以及关于这个问题的一些其他答案。下面是我编写的测试,它可以按照预期工作:
import * as fs from 'fs';
import * as _path from 'path';
import * as http2 from 'http2';
/* ... */
async function download( host, query, destination )
{
return new Promise
(
( resolve, reject ) =>
{
// Connect to client:
const client = http2.connect( host );
client.on( 'error', error => reject( error ) );
// Prepare a write stream:
const fullPath = _path.join( fs.realPathSync( '.' ), destination );
const file = fs.createWriteStream( fullPath, { flags: "wx" } );
file.on( 'error', error => reject( error ) );
// Create a request:
const request = client.request( { [':path']: query } );
// On initial response handle non-success (!== 200) status error:
request.on
(
'response',
( headers/*, flags*/ ) =>
{
if( headers[':status'] !== 200 )
{
file.close();
fs.unlink( fullPath, () => {} );
reject( new Error( `Server responded with ${headers[':status']}` ) );
}
}
);
// Set encoding for the payload:
request.setEncoding( 'utf8' );
// Write the payload to file:
request.on( 'data', chunk => file.write( chunk ) );
// Handle ending the request
request.on
(
'end',
() =>
{
file.close();
client.close();
resolve( { result: true } );
}
);
/*
You can use request.setTimeout( 12000, () => {} ) for aborting
after period of inactivity
*/
// Fire off [flush] the request:
request.end();
}
);
}
然后,例如:
/* ... */
let downloaded = await download( 'https://gitlab.com', '/api/v4/...', 'tmp/tmpFile' );
if( downloaded.result )
{
// Success!
}
// ...
外部引用
https://nodejs.org/api/http2.html#http2_client_side_example https://nodejs.org/api/http2.html#http2_clienthttp2session_request_headers_options
编辑信息
解决方案是为typescript编写的,函数是一个类方法——但是没有注意到这一点,如果没有正确使用函数声明,这个解决方案将无法为假定的javascript用户工作,这是我们的贡献者迅速添加的。谢谢!
您可以尝试使用res.redirect到https文件下载url,然后它将下载文件。
如:res.redirect(“https / / static.file.com/file.txt”);