nodejs中层-透传数据及文件

透传数据及文件

背景:

调用后台接口之前,需要按照约定统一规格化数据以及用户鉴权验证,因此管理端辅助开发代理接口,透传数据及文件给对应后台接口进行处理。

可能存在问题的点:

1、文件透传(是否可直接传递文件流?不方便处理采取何种方案?)
解决方案:
经沟通及验证,后台有严格的接收数据字符格式限制,暂定以bodyData的对象字符方式传送数据;因此文件传送需要一种变形方式,为保证不乱码,将获取到的文件buffer转为base64字符串,后台获取之后再生成对应文件。(不采取utf-8编码,因为其为3个字节表示,容易产生乱码;base64编码永远是4的倍速)

实现:

// 基于egg.js 处理文件的过程
async parseFileBase64(data, files) {
    const fileParseArr = (data._parseFileBase64 || '').split('|');
    if (files.length) {
      const eachFileMap = new Map();
      for (let j = 0; j < files.length; j++) {
        if (eachFileMap.has(files[j].field)) {
          eachFileMap.set(files[j].field, eachFileMap.get(files[j].field).concat([ files[j] ]));
        } else {
          eachFileMap.set(files[j].field, [ files[j] ]);
        }
      }
      for (const [ keys, values ] of eachFileMap) {
        if (fileParseArr.indexOf(keys.slice(0, -2)) !== -1) {
          if (values.length > 1) {
            for (let i = 0; i < values.length; i++) {
              data[keys.slice(0, -2) + '_' + i] = await fs.readFileSync(values[i].filepath).toString('base64');
            }
          } else if (values.length === 1) {
            data[keys.slice(0, -2)] = await fs.readFileSync(values[0].filepath).toString('base64');
          }
        }
      }
    } else {
      // 未上传则将文件属性名去除
      for (let i = 0; i < fileParseArr.length; i++) {
        delete data[fileParseArr[i]];
      }
    }
    return data;
  },

其他探究:

了解了下拿到文件之后透传文件,可借助辅助包:

// 常用上传
const req = urllib.request(buyUrl, {
  keepHeaderCase: true,
  headers: {
    'F-AUTH-APPID': 'F-AUTH-APPID', // 无关
  },
  files: {
    publicUploadFile: fs.createReadStream(ctx.request.files[0].filepath),
  },
  dataType: 'text',
  type: 'POST',
  data: bodyData,
}, function(err, data, res) {
  console.log('err, data, res ---> ', err, data, res);
});

// 选项: options.stream
const form = formstream();
form.file('publicUploadFile', ctx.request.files[0].filepath);
form.field('hello', '你好urllib');

const req = urllib.request(buyUrl, {
    method: 'POST',
    headers: form.headers(),
    stream: form,
}, function(err, data, res) {
    //data buffer格式
    console.log('err, data, res ---> ', err, data, res);
});

console.log('req ---> ', req);

注意:

Base64 编码将三个八位字节转换为四个编码字符,转码之后,文件字节数会增大1/3,因此需要合理估算大小;

拓展:

1、管理端文件上传:

js下,file基于Blob(可理解为web的二进制文件)实现的一个增加了关于文件有关信息的类;

上传方式:

1、form表单(点击其中的submit按钮,上传会刷新页面)
2、ajax + formdata(异步上传 + 局部更新页面,常用)
FormData 接口提供了一种表示表单数据的键值对 key/value 的构造方式,并且可以轻松的将数据通过XMLHttpRequest.send() 方法发送出去,本接口和此方法都相当简单直接。如果送出时的编码类型被设为 “multipart/form-data”,它会使用和表单一样的格式。

2、nodejs的buffer、stream、binary

详细解释
在缓冲区buffer中,我们可以操作正在流stream式传输的二进制数据binay或与之交互。
(buffer站台、stream巴士、binary乘客、一辆巴士的乘客chunk)
buffer存储在内存当中,大小有限,由C++层分配,不在V8中。stream操作期间会自动创建一个对应buffer,初次之外可创建自己的buffer进行数据交互。

// buffer常用方法
.toJSON() method presents the data as the Unicode Code Points of the characters
// { type: 'Buffer', data: [ 104, 101, 108, 108, 111, 32, 98, 117, 102, 102, 101, 114 ]}
.length
.write("Buffer really rocks!") 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值