当前位置: 首页 > article >正文

XmlHttpRequest responseType: ‘stream‘ 图片代理服务器

   它是一个存在于原生 XMLHttpRequest 对象中的属性。在 Web API 中,XMLHttpRequest 对象用于发送 HTTP 或 HTTPS 请求到服务器,并接收响应。responseType 属性就是用来指定预期从服务器返回的响应数据的类型。

默认值 


responseType的默认值为json,它还有其他可选值

  1. 'arraybuffer':表示服务器响应预计是 ArrayBuffer 形式,对于处理二进制数据非常有用。

  2. 'blob':表示服务器响应预计是二进制大对象(Blob)形式,通常用于处理文件或图像。

  3. 'document':表示服务器响应预计是一个 HTML Document 或 XML Document,这取决于接收到的数据的 MIME 类型。

  4. 'json':这是默认设置。表示服务器响应预计是 JSON 格式的。

  5. 'text':表示服务器响应预计是文本形式,包含在 DOMString 对象中。

  6. 'stream':在某些实现中,这个值允许你以流的形式接收响应数据,这在处理大文件或实时数据流时特别有用。在数据传输过程中就能读取已经下载的数据,而不是等到所有数据都下载完成

  7. 空字符串 (''):当 responseType 为空字符串时,它通常会采用默认类型,即 'text'。

responseType: 'stream' 的作用

  1. 内存优化:对于大文件或大量数据,将其全部加载到内存中可能会导致内存溢出或性能问题。通过设置 responseType: 'stream',你可以按需处理数据,每次只处理一小部分,从而有效管理内存使用。

  2. 实时处理:对于实时数据流,如视频流或实时日志,使用流可以确保你能够实时接收并处理数据,而不是等待整个数据流结束后再处理。

  3. 灵活性:通过流,你可以使用各种流处理库或工具来进一步处理数据,如转换、压缩、加密等。

  4. 错误处理:当使用流时,你可以监听错误事件,以便在数据传输过程中发生错误时进行处理。

在 Node.js 中,你可以使用流(Stream)的 API 来进一步操作这些数据,例如使用 .pipe() 方法将数据直接传输到另一个流(如文件写入流)或进行其他操作。

图片代理服务器

代理图片时候,如果需要等待图片下载完成才给客户端相遇数据,这样太慢了。如果在下载图片过程中就把数据推送给客户的,这样可以提高响应速度。

代码
const http = require('http');
const https = require('https');
const url = require('url');

const PORT = 3000; // 你的代理服务器端口  
const httpTool = (url, cb) => {
    console.log("https?", url.startsWith("https"), url)
    let ishttps = url.startsWith("https");
    if (ishttps) {
        return https.get(url, cb);
    }
    else {
        return http.get(url, cb);
    }

}
const server = http.createServer((req, res) => {
    const parsedUrl = url.parse(req.url, true);
    console.log("href", parsedUrl.query.url)
    const targetPath = parsedUrl.query.url;

    // 创建一个请求到原始图片服务器  
    const targetReq = httpTool(targetPath, (targetRes) => {
        // 将原始服务器的响应转发给客户端  
        res.writeHead(targetRes.statusCode, targetRes.headers);
        console.log("流数据接受中..")
        targetRes.pipe(res);
    });

    targetReq.on('error', (err) => {
        console.error(`请求 ${targetPath} 时出错:`, err);
        res.writeHead(500);
        res.end('图片代理服务器内部错误');
    });
});

server.listen(PORT, () => {
    console.log(`图片代理服务器正在运行,监听端口 ${PORT}`);
});
命令行


命令执行node index.js

文件本地起一个端口3000的代理服务器,拦截所有请求 

客户端请求地址

query url是要请求的真实图片

http://localhost:3000/?url=https://www.runoob.com/images/pulpit.jpg

这种方式可以避免浏览器跨域,更加细致的代理插件 http-proxy-middleware 

xmlhttprequest使用 stream

const xhr = new XMLHttpRequest();  
  
// 设置响应类型为流  
xhr.responseType = 'stream';  
  
// 打开请求  
xhr.open('GET', 'http://example.com/large-file', true);  
  
// 注册 onload 事件处理程序  
xhr.onload = function () {  
  if (this.status === 200) {  
    // 获取响应流  
    const reader = this.response;  
    const stream = reader.getReader();  
  
    // 读取流中的数据块  
    function read() {  
      stream.read().then(({ value, done }) => {  
        // 如果还有数据,处理 value(它是一个 Uint8Array)  
        if (value) {  
          // 在这里处理数据块,例如写入文件或进行其他操作  
          console.log(value);  
  
          // 继续读取流中的下一个数据块  
          read();  
        } else {  
          // 所有数据都已读取完毕  
          console.log('Stream reading complete.');  
        }  
      }).catch(error => {  
        console.error('Error reading stream:', error);  
      });  
    }  
  
    // 开始读取流  
    read();  
  } else {  
    console.error('Request failed with status', this.status);  
  }  
};  
  
// 注册 onerror 事件处理程序  
xhr.onerror = function () {  
  console.error('Request failed');  
};  
  
// 发送请求  
xhr.send();

 

axios使用stream

const express = require('express');  
const axios = require('axios'); // 用于发送 HTTP 请求  
const app = express();  
const PORT = 3000; // 代理服务器端口  
  
// 配置 Express 应用  
app.use(express.urlencoded({ extended: false }));  
app.use(express.json());  
  
// 代理图片请求的中间件  
function proxyImage(req, res, next) {  
  const targetUrl = `http://example.com${req.originalUrl}`; // 构造目标 URL  
  
  axios({  
    method: 'get',  
    url: targetUrl,  
    responseType: 'stream', // 响应类型设置为流  
  })  
  .then((response) => {  
    // 设置响应头  
    const headers = response.headers;  
    delete headers['content-length']; // 删除 content-length,因为流的长度未知  
    res.set(headers);  
      
    // 将响应流转发给客户端  
    response.data.pipe(res);  
  })  
  .catch((error) => {  
    console.error('Error fetching image:', error);  
    res.status(500).send('Error fetching image');  
  });  
}  
  
// 应用代理图片请求的中间件  
app.use('/images', proxyImage); // 所有以 '/images' 开头的请求都会被代理  
  
// 启动服务器  
app.listen(PORT, () => {  
  console.log(`图片代理服务器正在运行,监听端口 ${PORT}`);  
});


http://www.kler.cn/a/271508.html

相关文章:

  • java求职学习day23
  • SpringBoot+Vue的理解(含axios/ajax)-前后端交互前端篇
  • 一文大白话讲清楚webpack进阶——9——ModuleFederation实战
  • Leetcode 45. 跳跃游戏 II
  • 572. 另一棵树的子树
  • Pandas进行MongoDB数据库CRUD
  • 一款博客网站源码
  • 1.通过AD组策略如何做封禁高危端口的策略?AD域控如何给加域的电脑做指定端口号封禁呢?
  • JavaWeb--HTML
  • 相机拍照与摄影学基础
  • Rust镜像配置
  • 「黄钊的AI日报·第三季」正式发布!
  • redis中List和hash数据类型
  • Lucene查询语法,适用于 ELk Kibana 查询
  • 切面条-蓝桥杯?-Lua 中文代码解题第1题
  • 鸿蒙Harmony应用开发—ArkTS声明式开发(基础手势:TextTimer)
  • 掌握Go语言:深入理解Go语言中的数组和切片,灵活处理数据的利器(16)
  • [自研开源] MyData 数据集成之数据过滤 v0.7.2
  • Java基础 - 9 - 集合进阶(二)
  • 蓝桥杯2023年-松散子序列(dp)
  • 十五、自回归(AutoRegressive)和自编码(AutoEncoding)语言模型
  • 开源绘图工具 PlantUML 入门教程(常用于画类图、用例图、时序图等)
  • 数据清洗与预处理:打造高质量数据分析基础
  • LeetCode 395. 至少有K个重复字符的最长子串
  • RoketMQ主从搭建
  • c语言:于龙加