使用Node做一个文件代理中转
动图GIF由开源免费的
录制
Code
// 使用Node搭建一个简单的http服务器
// 加载http模块
let http = require('http')
let https = require('https')
var url = require("url");
// 调用http的createServer方法 创建一个服务器实例
let server = http.createServer()
// 监听request请求事件 设置请求处理函数
server.on('request', function (request, response) {
if (request.method === 'OPTIONS') {
response.setHeader('Access-Control-Allow-Origin', '*')
response.setHeader('Access-Control-Allow-Headers', '*')
response.setHeader('Access-Control-Allow-Methods', '*')
response.write('')
} else {
const data = url.parse(request.url)
// http://127.0.0.1:9988/source?path=https://mdn.github.io/learning-area/html/multimedia-and-embedding/video-and-audio-content/rabbit320.mp4
if (data.pathname === '/source') {
const path = new URLSearchParams(data.query).get('path')
const options = {
method: "GET",
responseType: 'blob',
headers: { // "Content-Type": "application/json"
}
};
const clientRequest = https.request(path, options, (incomingMessage) => {
// 设置headers
// const keys = Object.keys(incomingMessage.headers)
// for (let n of keys) {
// response.setHeader(n, incomingMessage.headers[n])
// }
response.setHeader('Access-Control-Allow-Origin', '*')
response.setHeader('Access-Control-Allow-Headers', '*')
response.setHeader('Access-Control-Allow-Methods', '*')
console.log(`状态码: ${
incomingMessage.statusCode
}`);
incomingMessage.on("data", (d) => { // process.stdout.write(d);
console.log(d.length)
response.write(d)
});
incomingMessage.on('end', () => {
response.end()
})
response.writeHead(incomingMessage.statusCode, incomingMessage.headers);
});
// POST
request.on('data', function (chunk) {
console.log('in request length:', chunk.length);
clientRequest.write(chunk, 'binary');
});
request.on('end', function () {
console.log('request end')
// 向proxy发送求情,这里end方法必须被调用才能发起代理请求
// 所有的客户端请求都需要通过end来发起
clientRequest.end();
});
clientRequest.on("error", (error) => {
console.error(error);
});
clientRequest.on('close', (val) => {
console.log('close')
})
// POST 请求会使用到这个
// clientRequest.write(JSON.stringify(data));
}
}
})
// 绑定端口号 启动服务
server.listen(9988, function () {
console.log('已经开启您的http服务器')
console.log('http://127.0.0.1:9988')
})
Use
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document Demo</title>
</head>
<body>
<button id="download">Download</button>
<script>
const download = document.querySelector("#download");
download.addEventListener("click", () => {
// 改变状态
download.disabled = true;
fetch();
});
function fetch() {
// 1. 创建一个 new XMLHttpRequest 对象
let xhr = new XMLHttpRequest();
xhr.responseType = "blob";
// 2. 配置它:从 URL /article/.../load GET-request
xhr.open(
"GET",
"http://127.0.0.1:9988/source?path=https://mdn.github.io/learning-area/html/multimedia-and-embedding/video-and-audio-content/rabbit320.mp4"
);
xhr.setRequestHeader("haha", "haha");
// 3. 通过网络发送请求
xhr.send();
// 4. 当接收到响应后,将调用此函数
xhr.onload = function () {
if (xhr.status != 200) {
// 分析响应的 HTTP 状态
console.log(`Error ${xhr.status}: ${xhr.statusText}`); // 例如 404: Not Found
} else {
// 显示结果
// console.log(`Done, got ${xhr.response.length} bytes`); // response 是服务器响应
console.log(`Done, got ${xhr.response.size} bytes`, xhr.response);
const download = document.createElement("a");
// 创建blob对象,将二进制数据封装为BLOB对象
// const blob = new Blob([res], {
// type: type
// })
const blob = xhr.response;
// 兼容webkix浏览器,处理webkit浏览器中herf自动添加blob前缀,默认在浏览器打开而不是下载
const URL = window.URL || window.webkitURL;
// 根据blob对象创建URL 对象,生成本地URL
const herf = URL.createObjectURL(blob);
download.href = herf;
// 下载链接
download.download = "123";
download.click();
// 改变状态
download.disabled = false;
// 在内存中移除URL 对象
window.URL.revokeObjectURL(herf);
}
};
xhr.onprogress = function (event) {
if (event.lengthComputable) {
console.log(`Received ${event.loaded} of ${event.total} bytes`);
} else {
console.log(
`Received ${event.loaded} bytes`,
"没有 Content-Length"
);
}
};
xhr.onerror = function () {
console.log("Request failed");
};
}
</script>
</body>
</html>