使用Node做一个文件代理中转

文件代理.gif

动图GIF由开源免费的

录制

Code

  1. // 使用Node搭建一个简单的http服务器
  2. // 加载http模块
  3. let http = require('http')
  4. let https = require('https')
  5. var url = require("url");
  6. // 调用http的createServer方法 创建一个服务器实例
  7. let server = http.createServer()
  8. // 监听request请求事件 设置请求处理函数
  9. server.on('request', function (request, response) {
  10. if (request.method === 'OPTIONS') {
  11. response.setHeader('Access-Control-Allow-Origin', '*')
  12. response.setHeader('Access-Control-Allow-Headers', '*')
  13. response.setHeader('Access-Control-Allow-Methods', '*')
  14. response.write('')
  15. } else {
  16. const data = url.parse(request.url)
  17. // http://127.0.0.1:9988/source?path=https://mdn.github.io/learning-area/html/multimedia-and-embedding/video-and-audio-content/rabbit320.mp4
  18. if (data.pathname === '/source') {
  19. const path = new URLSearchParams(data.query).get('path')
  20. const options = {
  21. method: "GET",
  22. responseType: 'blob',
  23. headers: { // "Content-Type": "application/json"
  24. }
  25. };
  26. const clientRequest = https.request(path, options, (incomingMessage) => {
  27. // 设置headers
  28. // const keys = Object.keys(incomingMessage.headers)
  29. // for (let n of keys) {
  30. // response.setHeader(n, incomingMessage.headers[n])
  31. // }
  32. response.setHeader('Access-Control-Allow-Origin', '*')
  33. response.setHeader('Access-Control-Allow-Headers', '*')
  34. response.setHeader('Access-Control-Allow-Methods', '*')
  35. console.log(`状态码: ${
  36. incomingMessage.statusCode
  37. }`);
  38. incomingMessage.on("data", (d) => { // process.stdout.write(d);
  39. console.log(d.length)
  40. response.write(d)
  41. });
  42. incomingMessage.on('end', () => {
  43. response.end()
  44. })
  45. response.writeHead(incomingMessage.statusCode, incomingMessage.headers);
  46. });
  47. // POST
  48. request.on('data', function (chunk) {
  49. console.log('in request length:', chunk.length);
  50. clientRequest.write(chunk, 'binary');
  51. });
  52. request.on('end', function () {
  53. console.log('request end')
  54. // 向proxy发送求情,这里end方法必须被调用才能发起代理请求
  55. // 所有的客户端请求都需要通过end来发起
  56. clientRequest.end();
  57. });
  58. clientRequest.on("error", (error) => {
  59. console.error(error);
  60. });
  61. clientRequest.on('close', (val) => {
  62. console.log('close')
  63. })
  64. // POST 请求会使用到这个
  65. // clientRequest.write(JSON.stringify(data));
  66. }
  67. }
  68. })
  69. // 绑定端口号 启动服务
  70. server.listen(9988, function () {
  71. console.log('已经开启您的http服务器')
  72. console.log('http://127.0.0.1:9988')
  73. })

Use

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  7. <title>Document Demo</title>
  8. </head>
  9. <body>
  10. <button id="download">Download</button>
  11. <script>
  12. const download = document.querySelector("#download");
  13. download.addEventListener("click", () => {
  14. // 改变状态
  15. download.disabled = true;
  16. fetch();
  17. });
  18. function fetch() {
  19. // 1. 创建一个 new XMLHttpRequest 对象
  20. let xhr = new XMLHttpRequest();
  21. xhr.responseType = "blob";
  22. // 2. 配置它:从 URL /article/.../load GET-request
  23. xhr.open(
  24. "GET",
  25. "http://127.0.0.1:9988/source?path=https://mdn.github.io/learning-area/html/multimedia-and-embedding/video-and-audio-content/rabbit320.mp4"
  26. );
  27. xhr.setRequestHeader("haha", "haha");
  28. // 3. 通过网络发送请求
  29. xhr.send();
  30. // 4. 当接收到响应后,将调用此函数
  31. xhr.onload = function () {
  32. if (xhr.status != 200) {
  33. // 分析响应的 HTTP 状态
  34. console.log(`Error ${xhr.status}: ${xhr.statusText}`); // 例如 404: Not Found
  35. } else {
  36. // 显示结果
  37. // console.log(`Done, got ${xhr.response.length} bytes`); // response 是服务器响应
  38. console.log(`Done, got ${xhr.response.size} bytes`, xhr.response);
  39. const download = document.createElement("a");
  40. // 创建blob对象,将二进制数据封装为BLOB对象
  41. // const blob = new Blob([res], {
  42. // type: type
  43. // })
  44. const blob = xhr.response;
  45. // 兼容webkix浏览器,处理webkit浏览器中herf自动添加blob前缀,默认在浏览器打开而不是下载
  46. const URL = window.URL || window.webkitURL;
  47. // 根据blob对象创建URL 对象,生成本地URL
  48. const herf = URL.createObjectURL(blob);
  49. download.href = herf;
  50. // 下载链接
  51. download.download = "123";
  52. download.click();
  53. // 改变状态
  54. download.disabled = false;
  55. // 在内存中移除URL 对象
  56. window.URL.revokeObjectURL(herf);
  57. }
  58. };
  59. xhr.onprogress = function (event) {
  60. if (event.lengthComputable) {
  61. console.log(`Received ${event.loaded} of ${event.total} bytes`);
  62. } else {
  63. console.log(
  64. `Received ${event.loaded} bytes`,
  65. "没有 Content-Length"
  66. );
  67. }
  68. };
  69. xhr.onerror = function () {
  70. console.log("Request failed");
  71. };
  72. }
  73. </script>
  74. </body>
  75. </html>