微信小程序获取图片使用session(下篇)

概述:

在本人上一篇文章中,微信小程序获取图片使用session(上篇),文章地址:https://blog.csdn.net/shenweihong/article/details/144970945,提出来性能问题,图片比较大的(超过1M)导致小程序setData渲染效率低,本文基于这个问题,描述解决方法。

开发平台:

前端:微信开发者工具,采用原生的js,基础库版本:3.6.5

后台:eclipse,springboot架构,springboot版本:2.6.13

原理:

文章:微信小程序获取图片使用session(上篇),把cookie放在http head中,

1、这里前端我就把cookie直接放在url中 ,前端只需要处理image属性src的url,不需要手动处理http请求,这个url能不受限制访问后台;

2、后台从请求的url中分离出cookie,和拿到真正想请求的image地址;

3、后台再发起一个http get请求,这个请求带有cookie请求到之前登陆的session中获取。

如下图:

其中两处的后台,是同一个后台程序,只是url不一样

前端代码:

wxml文件

javascript 复制代码
<view class="grid-container">
  <view class="grid-item" wx:for="{{itemsShow}}" wx:for-item="item" wx:for-index="index" wx:key="*this">
    <image class="image-item" src="{{item.pic}}" bindtap="{{item.act}}"></image>
    <text>{{item.tag}}</text>
  </view>
</view>

js文件

javascript 复制代码
data: {
    itemsShowPreurl: "/Function/WxTopWorkRecord/GetFunctionLogo/",
    itemsShow:[],
    itemsShowKeep:[],
    itemsShowOrg: [
      {
        tag: "会议",
        pic: "metting",
        act: "onclickFunMetting"
      },
      {
        tag: "记事",
        pic: "record",
        act: "onclickFunNoteBook"
      },
      {
        tag: "借录",
        pic: "borrow",
        act: "onclickFunBorrow"
      },
      {
        tag: "密码",
        pic: "password",
        act: "onclickFunPassword"
      },
      {
        tag: "系统",
        pic: "system",
        act: "onclickFunSystem"
      },
    ]
  },


setItemsShowData(cl) {
    var i = 0;
    var tmpStr = null;

    if (cl.data.itemsShowKeep == null || cl.data.itemsShowKeep.length <= 0) {
      for (i = 0; i < cl.data.itemsShowOrg.length; i++) {
        cl.data.itemsShowKeep.push({
          tag: "",
          pic: "",
          act: ""
        });
        cl.data.itemsShowKeep[i].tag = cl.data.itemsShowOrg[i].tag;
        cl.data.itemsShowKeep[i].act = cl.data.itemsShowOrg[i].act;
      }
    }

    for (i = 0; i < cl.data.itemsShowOrg.length; i++) {
      tmpStr = app.globalData.baseUrl + "/Guest/WxConvert/" + js_util.util_utf8_str_to_hex(app.globalData.coockieStr, false) + cl.data.itemsShowPreurl + cl.data.itemsShowOrg[i].pic;
      cl.data.itemsShowKeep[i].pic = tmpStr; 
    }  
                
    cl.setData({
      itemsShow : cl.data.itemsShowKeep
    });     
  },

这里用到了一个临时变量itemsShowKeep,最终的前端刷新显示在变量itemsShow

app.globalData.baseUrl为请求的基础url,这个/Guest/WxConvert/为公共请求的url,辅助字符转十六进制字符函数:js_util.util_utf8_str_to_hex,如下代码

javascript 复制代码
function util_utf8_str_to_hex(charStr, isToArray) {
  var i = 0;
  var ch = 0;
  var result = "";

  for (i = 0; i < charStr.length; i++) {   
    ch = charStr.charCodeAt(i);
    if (ch <= 0x7F) {
      result += hex_digits.charAt((ch >>> 4) & 0x0f);
      result += hex_digits.charAt((ch) & 0x0f);
    } else if (ch >= 0x80 && ch <= 0x7FF) {
      result += hex_digits.charAt(((0xC0 + (ch >> 6)) >>> 4) & 0x0f);
      result += hex_digits.charAt((0xC0 + (ch >> 6)) & 0x0f);
      result += hex_digits.charAt(((0x80 + (ch & 0x3F)) >>> 4) & 0x0f);
      result += hex_digits.charAt((0x80 + (ch & 0x3F)) & 0x0f);
    } else if (ch >= 0x800 && ch <= 0xFFFF) {
      result += hex_digits.charAt(((0xE0 + (ch >> 12)) >>> 4) & 0x0f);
      result += hex_digits.charAt((0xE0 + (ch >> 12)) & 0x0f);
      result += hex_digits.charAt(((0x80 + (0x3F & (ch >> 6))) >>> 4) & 0x0f);
      result += hex_digits.charAt((0x80 + (0x3F & (ch >> 6))) & 0x0f);
      result += hex_digits.charAt(((0x80 + (ch & 0x3F)) >>> 4) & 0x0f);
      result += hex_digits.charAt((0x80 + (ch & 0x3F)) & 0x0f);
    }
  }

  if (isToArray) {
    return util_hex_char_to_array(result);
  }
  return result;
}

function util_hex_char_to_array(hexStrIn) {
  var i = 0;
  var cnt = 0;
  var ele = 0;
  var bytesArray = null;

  cnt = 0;
  for (i = 0; i < hexStrIn.length; i++) {
    ele = hexStrIn.charCodeAt(i);
    if (ele >= 48 && ele < 48 + 10) {
      cnt++;
    }
    if (ele >= 65 && ele < 65 + 6) {
      cnt++;
    }
    if (ele >= 97 && ele < 97 + 6) {
      cnt++;
    }
  }
  bytesArray = new Uint8Array(parseInt((cnt + 1) / 2));
  cnt = 0;
  for (i = 0; i < hexStrIn.length; i++) {
    ele = hexStrIn.charCodeAt(i);
    if (ele >= 48 && ele < 48 + 10) {
      ele -= 48;
      cnt++;
    } else if (ele >= 65 && ele < 65 + 6) {
      ele = ele - 65 + 10;
      cnt++;
    } else if (ele >= 97 && ele < 97 + 6) {
      ele = ele - 97 + 10;
      cnt++;
    } else {
      continue;
    }
    if ((cnt % 2) == 1) {
      bytesArray[parseInt((cnt - 1) / 2)] = (ele << 4) & 0xF0;
    } else {
      bytesArray[parseInt((cnt - 1) / 2)] |= ele;
    }
  }

  return bytesArray;
}

后台代码:

公共请求

java 复制代码
@Controller
public class ControllerWxConvertSessionGet {
	
	@RequestMapping(value = "/Guest/WxConvert/{cookie}/**", method = RequestMethod.GET)
	public void WxConvert(@PathVariable("cookie") String cookieStr, HttpServletRequest request, HttpServletResponse response) {
		String getUri = null;
		
		request.getRequestURL();
		
		try {
			getUri = getReqProHostPort(request) + DivGetTrueUri(request);
			System.out.println("DivGetTrueUri = " + getUri);
			System.out.println("cookieStr = " + (new String(DataConvert.stringToHex(cookieStr))));
			if (getUri.startsWith("https")) {
				HttpClient.HttpsGet(response, new String(DataConvert.stringToHex(cookieStr)), getUri);
			} else {
				HttpClient.HttpGet(response, new String(DataConvert.stringToHex(cookieStr)), getUri);
			}
		} catch (MyErrorException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return;
		} catch (SocketException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return;  
		}		
	}
	
	private String DivGetTrueUri(HttpServletRequest request) throws MyErrorException {
		String orgUri = request.getRequestURI();
		int i = 0;
		int j = 0;
		
		if (orgUri == null) {
			throw new MyErrorException("获取原uri为空");
		}
		if (orgUri.startsWith("/Guest/WxConvert/") == false) {
			throw new MyErrorException("原uri前缀不匹配");
		}
		i = "/Guest/WxConvert/".length();
		j = orgUri.indexOf('/', i);
		if (j <= 0 || j <= i) {
			throw new MyErrorException("没有找到路径");
		}
		
		return orgUri.substring(j);
	}
	
	public static StringBuffer getReqProHostPort(HttpServletRequest request) {
        StringBuffer url = new StringBuffer();
        String scheme = request.getScheme();
        int port = request.getServerPort();
        if (port < 0) {
            // Work around java.net.URL bug
            port = 80;
        }

        url.append(scheme);
        url.append("://");
        url.append(request.getServerName());
        if ((scheme.equals("http") && (port != 80))
            || (scheme.equals("https") && (port != 443))) {
            url.append(':');
            url.append(port);
        }
        //url.append(request.getRequestURI());

        return url;
    }
	
}

http(s)辅助函数

javascript 复制代码
	public static void HttpGet(HttpServletResponse response, String cookie, String toUrl) throws SocketException {		
		String strTmp = null;
		byte[] tmpBytes = null;
		InputStream inStream = null;
		try {
            URL url = new URL(toUrl);
	        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
           	connection.setRequestMethod("GET");
            //connection.setRequestProperty("Content-Type", "application/json");
            connection.setConnectTimeout(10000);
            connection.setReadTimeout(20000);
            connection.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)");
            connection.setRequestProperty("Cookie", cookie);
            connection.setDoOutput(true);
            connection.setDoInput(true);
            connection.connect();
            //tmpBytes = bodyData;
            
            //connection.getOutputStream().write(tmpBytes);
           // strTmp = "";
           int responseCode = connection.getResponseCode();           
           System.out.println("responseCode = " + responseCode);
           if (responseCode == 200) {
        	   inStream = connection.getInputStream();
        	   if (response != null) {
        		   response.setStatus(responseCode);
        		   MyStream.readAllToOutStream(inStream, response.getOutputStream());
        	   }
        	   //tmpBytes = MyStream.readAllBytes(inStream);
        	   //strTmp = (new String(tmpBytes));
        	   //System.out.println("post readAllBytes = " + strTmp);        	  
        	   inStream.close();
           } else {      	   
        	   strTmp = connection.getResponseMessage();
        	   if (response != null) {
	        	   if (strTmp != null && strTmp.length() > 0) {
	        		   response.setStatus(responseCode, strTmp);
	        	   } else {
	        		   response.setStatus(responseCode);
	        	   }
        	   }
        	   strTmp = "";
           }
            connection.disconnect();
        } catch (java.net.ConnectException e) {
        	throw e;
        } catch (java.net.SocketException e) {
        	throw e;
        }catch (Exception e) {
            e.printStackTrace();
        }
		
		//if (strTmp == null) {
		//	strTmp = "";
		//}
		
		//return strTmp;
	} 
	
	public static void HttpsGet(HttpServletResponse response, String cookie, String toUrl) throws SocketException {		
		String strTmp = null;
		byte[] tmpBytes = null;
		InputStream inStream = null;
		try {
            URL url = new URL(toUrl);
	        HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
	        connection.setHostnameVerifier(allHostsValid);
           	connection.setRequestMethod("GET");
            //connection.setRequestProperty("Content-Type", "application/json");
            connection.setConnectTimeout(10000);
            connection.setReadTimeout(20000);
            connection.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)");
            connection.setRequestProperty("Cookie", cookie);
            connection.setDoOutput(true);
            connection.setDoInput(true);
           // connection.setSSLSocketFactory(createSSLSocketFactory());
            connection.connect();
            //tmpBytes = bodyData;
            
            //connection.getOutputStream().write(tmpBytes);
           // strTmp = "";
           int responseCode = connection.getResponseCode();           
           System.out.println("responseCode = " + responseCode);
           if (responseCode == 200) {
        	   inStream = connection.getInputStream();
        	   if (response != null) {
        		   response.setStatus(responseCode);
        		   MyStream.readAllToOutStream(inStream, response.getOutputStream());
        	   }
        	   //tmpBytes = MyStream.readAllBytes(inStream);
        	   //strTmp = (new String(tmpBytes));
        	   //System.out.println("post readAllBytes = " + strTmp);        	  
        	   inStream.close();
           } else {      	   
        	   strTmp = connection.getResponseMessage();
        	   if (response != null) {
	        	   if (strTmp != null && strTmp.length() > 0) {
	        		   response.setStatus(responseCode, strTmp);
	        	   } else {
	        		   response.setStatus(responseCode);
	        	   }
        	   }
        	   strTmp = "";
           }
            connection.disconnect();
        } catch (java.net.ConnectException e) {
        	throw e;
        } catch (java.net.SocketException e) {
        	throw e;
        }catch (Exception e) {
            e.printStackTrace();
        }
		
		//if (strTmp == null) {
		//	strTmp = "";
		//}
		
		//return strTmp;
	} 
	
	private static HostnameVerifier allHostsValid = new HostnameVerifier() {
		@Override
		public boolean verify(String hostname, SSLSession session) {
			return true;
		}

	};

	private static SSLSocketFactory createSSLSocketFactory() {
		TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
			@Override
			public void checkClientTrusted(X509Certificate[] chain, String authType) {
			}

			@Override
			public void checkServerTrusted(X509Certificate[] chain, String authType) {
			}

			@Override
			public X509Certificate[] getAcceptedIssuers() {
				return new X509Certificate[] {};
			}
		} };

		// 使用上述TrustManager初始化SSLContext
		SSLContext sslContext = null;
		try {
			sslContext = SSLContext.getInstance("SSL");
			sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (KeyManagementException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		// 创建一个不进行主机名验证的SSLConnectionSocketFactory
		return sslContext.getSocketFactory();
	}

最终请求资源的地方

java 复制代码
package com.shenweihong.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

import com.shenweihong.html.ResponseFile;
import com.shenweihong.main.UserDir;

@Controller
public class ControllerWxTopWorkRecord {
	@GetMapping("/Function/WxTopWorkRecord/GetFunctionLogo/{PicName}")
	public void GetFunctionLogo(@PathVariable("PicName") String picName, HttpServletRequest request, HttpServletResponse response) {
		System.out.println("picName = " + picName);
		response.setContentType("image/jpeg");
		ResponseFile.ResponseWriteStreamFile(UserDir.GetResourceDir() + "static/wx_image/public/" + picName + ".jpg", response);
	}  
}
相关推荐
2501_915918416 小时前
Web 前端可视化开发工具对比 低代码平台、可视化搭建工具、前端可视化编辑器与在线可视化开发环境的实战分析
前端·低代码·ios·小程序·uni-app·编辑器·iphone
2501_915106327 小时前
iOS 使用记录和能耗监控实战,如何查看电池电量消耗、App 使用时长与性能数据(uni-app 开发调试必备指南)
android·ios·小程序·uni-app·cocoa·iphone·webview
じòぴé南冸じょうげん15 小时前
小程序的project.private.config.json是无依赖文件,那可以删除吗?
前端·小程序·json
2501_9160137416 小时前
HTTPS 抓包难点分析,从端口到工具的实战应对
网络协议·http·ios·小程序·https·uni-app·iphone
2501_9159184118 小时前
uni-app 项目 iOS 上架效率优化 从工具选择到流程改进的实战经验
android·ios·小程序·uni-app·cocoa·iphone·webview
00后程序员张18 小时前
如何在不同 iOS 设备上测试和上架 uni-app 应用 实战全流程解析
android·ios·小程序·https·uni-app·iphone·webview
微三云-轩19 小时前
区块链:重构企业数字化的信任核心与创新动力
人工智能·小程序·区块链·生活·我店
阿隆_趣编程21 小时前
为了方便相亲,我用AI写了一款小程序
前端·javascript·微信小程序
2501_915918412 天前
iOS 开发全流程实战 基于 uni-app 的 iOS 应用开发、打包、测试与上架流程详解
android·ios·小程序·https·uni-app·iphone·webview
黑马源码库miui520862 天前
JAVA同城打车小程序APP打车顺风车滴滴车跑腿源码微信小程序打车源码
java·微信·微信小程序·小程序·uni-app