微信小程序 实现带 header 参数获取图片并展示

问题

一开始是这样的,项目的小程序是用了云服务器做了代理,从而访问目标服务器,获取到所需要的的数据。而要想获取到数据,需要在请求中在 header 添加固定参数才能获取到。

所以我在自己统一封装的 wx.request 中添加对应所需要的的字段。

js 复制代码
var mid = wx.getStorageSync('userData').mid;
let header = {
    'Machine-Id': mid,
}
wx.request({
    url: BaseURL + url,
    data: data,
    method: method,
    header: header,
)}

这样每次发起请求都会默认携带我所需要的的参数,但是这时候出现一个问题,我请求出来的图片路径放在 image 标签显示不出来。

正常情况下 image 中的 src 属性是图片的路径或者网络链接,就可以正常显示,是因为 image 默认帮你以 src 自动发起请求,并将请求到的数据展示出来。

但是我想要访问到服务器都是需要携带 header 的参数,它自动发起请求就走不到我封装的请求,所以图片就获取不到了。

这时候就需要自己去利用获取到的图片路径去做请求。其中 responseType 的值为表示响应的数据类型为 arraybuffer

ArrayBuffer

是 JavaScript 中的一种数据类型,用于表示一段二进制数据的缓冲区。它可以存储各种类型的数据,例如整数、浮点数、布尔值以及其他复杂的数据结构。但是这种数据类型不被 src 所接受。

js 复制代码
wx.request({
      url: ImgBaseURL + url,
      header,
      responseType: 'arraybuffer',
      success: res => {
          console.log(res.data) // 输出图片的二进制数据
      }
    })

获取到想要的图片数据了,转换为base64格式数据,就可以进行图片的显示。这时候问题又来了,在微信小程序文档中提供的 wx.arrayBufferToBase64 方法在基础库版本 2.4.0 起已废弃,并不推荐使用。

既然用不了这个方法,就要自己去实现了,在浏览器中,就可以通过 Uint8Array 以及 window 对象中的 btoa 就可以完美解决。但是小程序也使用不了 btoa 的。

base64.js

通过该 base64.js 文件去实现 btoa 方法, 使用 module.exports 导出方法,通过 import { btoa } from './base64' 使用到 base.js 方法。

js 复制代码
var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",
  a256 = '',
  r64 = [256],
  r256 = [256],
  i = 0;
var UTF8 = {
  encode: function (strUni) { // use regular expressions & String.replace callback function for better efficiency    // than procedural approaches    
    var strUtf = strUni.replace(/[\u0080-\u07ff]/g, // U+0080 - U+07FF => 2 bytes 110yyyyy, 10zzzzzz      
      function (c) {
        var cc = c.charCodeAt(0);
        return String.fromCharCode(0xc0 | cc >> 6, 0x80 | cc & 0x3f);
      }).replace(/[\u0800-\uffff]/g, // U+0800 - U+FFFF => 3 bytes 1110xxxx, 10yyyyyy, 10zzzzzz        
      function (c) {
        var cc = c.charCodeAt(0);
        return String.fromCharCode(0xe0 | cc >> 12, 0x80 | cc >> 6 & 0x3F, 0x80 | cc & 0x3f);
      });
    return strUtf;
  },
  decode: function (strUtf) { // note: decode 3-byte chars first as decoded 2-byte strings could appear to be 3-byte char! 
    var strUni = strUtf.replace(/[\u00e0-\u00ef][\u0080-\u00bf][\u0080-\u00bf]/g, // 3-byte chars     
      function (c) { // (note parentheses for precence)        
        var cc = ((c.charCodeAt(0) & 0x0f) << 12) | ((c.charCodeAt(1) & 0x3f) << 6) | (c.charCodeAt(2) & 0x3f);
        return String.fromCharCode(cc);
      }).replace(/[\u00c0-\u00df][\u0080-\u00bf]/g, // 2-byte chars        
      function (c) { // (note parentheses for precence)          
        var cc = (c.charCodeAt(0) & 0x1f) << 6 | c.charCodeAt(1) & 0x3f;
        return String.fromCharCode(cc);
      });
    return strUni;
  }
};
while (i < 256) {
  var c = String.fromCharCode(i);
  a256 += c;
  r256[i] = i;
  r64[i] = b64.indexOf(c);
  ++i;
}

function code(s, discard, alpha, beta, w1, w2) {
  s = String(s);
  var buffer = 0,
    i = 0,
    length = s.length,
    result = '',
    bitsInBuffer = 0;
  while (i < length) {
    var c = s.charCodeAt(i);
    c = c < 256 ? alpha[c] : -1;
    buffer = (buffer << w1) + c;
    bitsInBuffer += w1;
    while (bitsInBuffer >= w2) {
      bitsInBuffer -= w2;
      var tmp = buffer >> bitsInBuffer;
      result += beta.charAt(tmp);
      buffer ^= tmp << bitsInBuffer;
    }++i;
  }
  if (!discard && bitsInBuffer > 0) result += beta.charAt(buffer << (w2 - bitsInBuffer));
  return result;
}
var Plugin = function (dir, input, encode) {
  return input ? Plugin[dir](input, encode) : dir ? null : this;
};
Plugin.btoa = Plugin.encode = function (plain, utf8encode) {
  plain = Plugin.raw === false || Plugin.utf8encode || utf8encode ? UTF8.encode(plain) : plain;
  plain = code(plain, false, r256, b64, 8, 6);
  return plain + '===='.slice((plain.length % 4) || 4);
};
Plugin.atob = Plugin.decode = function (coded, utf8decode) {
  coded = coded.replace(/[^A-Za-z0-9\+\/\=]/g, "");
  coded = String(coded).split('=');
  var i = coded.length;
  do {
    --i;
    coded[i] = code(coded[i], true, r64, a256, 6, 8);
  } while (i > 0);
  coded = coded.join('');
  return Plugin.raw === false || Plugin.utf8decode || utf8decode ? UTF8.decode(coded) : coded;
};
module.exports = {
  btoa: Plugin.btoa,
  atob: Plugin.atob
}

二进制 转 base64

这个时候就可以用返回的数据放到 image 的 src 属性上。

js 复制代码
wx.request({
      url: ImgBaseURL + url,
      header,
      responseType: 'arraybuffer',
      success: res => {
          console.log(res.data) // 输出图片的二进制数据
          const str = String.fromCharCode(...new Uint8Array(res.data));
          return `data:image/jpeg;base64,${btoa(str)}`
      }
    })
相关推荐
崔庆才丨静觅10 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby606111 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了11 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅11 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅11 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅12 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment12 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅12 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊12 小时前
jwt介绍
前端
爱敲代码的小鱼12 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax