javascript - 使用ajax处理附件
问题描述
警告: 我正在制作一个 youtube 视频下载器。我仅出于教育目的制作此内容,并不意味着将其用于任何盗版/非法目的。
好的,直奔问题。我有一个运行脚本的 Node.js express 服务器,因此当您向它发送 get 请求时,它要么发送一些包含错误代码和内容的 JSON,要么发送一个 mp3 或 mp4 文件。我没有所有的代码,这是代码:
// Import some libraries
const express = require('express')
const ytdl = require('ytdl-core')
const cp = require('child_process')
var app = express()
app.get('/download', async (req, res) => {
const url = req.query.url
if (url == null) {
res.header('Access-Control-Allow-Origin','*')
res.send({err: 'URLNULL', errCode: 1})
return;
}
if (!ytdl.validateURL(url)) {
res.header('Access-Control-Allow-Origin','*')
res.send({err: 'INVALIDURL', errCode: 1})
return;
}
if (req.query.audioonly == 'true') {
const title = (await ytdl.getBasicInfo(url)).videoDetails.title
const audio = ytdl(url, {
quality: 'highestaudio'
}).on('error', (err) => {
if (err.message == 'unable to get local issuer certificate') {
res.send({err: 'CERTERR', errCode: 1})
return;
} else {
res.send({err: err.message, errCode: 2})
}
})
var ffmpegProcess = cp.spawn('ffmpeg', [
'-hide_banner',
'-loglevel', 'fatal',
'-i', 'pipe:3',
'-f', 'mp3',
'pipe:1'
], {
stdio: [
'inherit', 'pipe', 'inherit',
'pipe',
]
})
audio.pipe(ffmpegProcess.stdio[3])
res.header( 'Access-Control-Allow-Origin','*');
res.header('Content-Type', 'audio/mp3')
res.header('Access-Control-Expose-Headers', 'Content-Disposition')
res.header('Content-Disposition', `attachment; filename=${title}.mp3`)
ffmpegProcess.stdout.pipe(res)
} else {
const title = (await ytdl.getBasicInfo(url)).videoDetails.title
const video = ytdl(url, {
quality: 'highestvideo'
})
const audio = ytdl(url, {
quality: 'highestaudio'
})
var ffmpegProcess = cp.spawn('ffmpeg', [
'-hide_banner',
'-loglevel', 'fatal',
'-i', 'pipe:3',
'-i', 'pipe:4',
'-map', '0:v',
'-map', '1:a',
'-c', 'copy',
'-movflags', 'frag_keyframe+empty_moov',
'-f', 'mp4',
'pipe:1',
], {
stdio: [
'inherit', 'pipe', 'inherit',
'pipe', 'pipe',
]
})
video.pipe(ffmpegProcess.stdio[3])
audio.pipe(ffmpegProcess.stdio[4])
res.header( 'Access-Control-Allow-Origin','*');
res.header('Content-Type', 'video/mp4')
res.header('Access-Control-Expose-Headers', 'Content-Disposition')
res.header('Content-Disposition', `attachment; filename=${title}.mp4`);
ffmpegProcess.stdout.pipe(res)
}
})
app.listen(4443)
当我发送一个 GET 请求时,错误的东西工作正常,但是当我收到它时,我似乎找不到下载 mp3/mp4 的正确方法。这是我当前向服务器发送请求的前端 js 函数。
function dlmp3() {
if (input.value == null) {
//TODO: Handle error
}
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var binaryData = [];
binaryData.push(this.response);
var fileName = this.getResponseHeader("Content-Disposition") //if you have the fileName header available
console.log(fileName)
var link=document.createElement('a');
link.href=window.URL.createObjectURL(new Blob(binaryData, {type: "audio/mp3"}));
link.download=fileName;
link.click();
link.remove()
}
};
xhttp.open("GET", `http://localhost:4443/download?url=${input.value}&audioonly=true`, true);
xhttp.send();
}
这是一种非常粗略的方法,但它是它做某事的唯一方法(当然,吐出错误除外)。它确实下载了一些东西,但是当我从浏览器转到快速/下载链接时,mp3 比实际大小多 300 kb。此外,它是腐败的。有没有更好的方法来下载附件(我可以使用 Ajax 以外的东西)?
解决方案
推荐阅读
- javascript - 在缓冲区AudioContext JS之间播放音频而没有静音
- reactjs - 如何将多个网格容器包装在 React Fragment 元素中
- redux - 覆盖 SAP Spartacus 中的默认减速器
- python - 使用python很难从png文件中读取文本
- typescript - 如何在引用另一个对象的打字稿中获取模板化对象的值?
- tensorflow - 张量流.js | tensorflowjs_converter| keras 模型(model.js)非常慢(延迟)
- google-cloud-platform - 为什么我在 Google 的 Python TTS 示例中收到“invalid_grant:无效的 JWT 签名”?
- javascript - TypeError:input.includes 不是函数
- javascript - 使用 expressJS 和 socket.io 在手机上通过后端服务器访问网站
- javascript - 如何按属性对对象进行排序?