详解微信小程序 wx.uploadFile 的编码坑


Posted in Javascript onJanuary 23, 2017

编写微信小程序时,用到 wx.uploadFile,用来上传图片+文本信息.然而在编写过程中,由于官方的 demo 和文档描述很少,在几个坑上耗费了不少时间.

这里分享一个和编码有关的坑,主要是由于真机预览时 formData 中的非字母、数字的 ASCII 编码的字符如中文、泰文传输到服务端将不会自动进行转码码,并会会产生乱码及溢出,从而导致错误。

微信的 uploadFile 类似与 html 中的form带文件上传的表单 ( enctype=”multipart/form-data” ), 这样 post 上传的表单,可以包含文件,同时包含其它的键值数据。微信小程序用 uploadFile 实现类似的操作. 我的微信小程序端的uploadFile 代码如下 :

wx.uploadFile({
      url: 'https://<upload_domain>/save',
      filePath:photoPath, //待上传的图片,由 chooseImage获得
      name:'food_image',
      formData: {
       latitude:0.0,
       longitude:0.0,
       restaurant_id:0,
       city:'北京',
       name:'beijing' // 名称
      }, // HTTP 请求中其他额外的 form data
      success: function(res){
       console.log("addfood success",res);
      },
      fail: function(res) {
       console.log("addfood fail",res);
      },
     })
},

服务端我用的 php 编写,这里接受文件的接口为 save ,我将 POST和_FILES 里的数据直接输出到info.log 文件中用来进行调试.代码如下:

public function save(Request $request)
{
  error_log("FILES:" . json_encode($_FILES) . "\r\n", 3, "./logs/info.log");
  error_log("POST: " . json_encode($_POST) . "\r\n", 3, "./logs/info.log");
  error_log("city: " . $_POST["city"] . "\r\n", 3, "./logs/info.log");
  error_log("name: " . $_POST["name"] . "\r\n", 3, "./logs/info.log");
  error_log("latitude: " . $_POST["latitude"] . "\r\n", 3, "./logs/info.log");
  error_log("longitude: " . $_POST["longitude"] . "\r\n", 3, "./logs/info.log");
  error_log("restaurant_id: " . $_POST["restaurant_id"] . "\r\n", 3, "./logs/info.log");
  error_log("tags: " . $_POST["city"] . "\r\n", 3, "./logs/info.log");
echo 'success';
}

在小程序开发工具中运行小程序,选择好图片后进行上传操作,服务器端成功接收到数据,info.log输出的数据信息如下:

FILES:{"food_image":{"name":"store_265332457o6zAJszC4WsrwhUy55eh7iKJt7EQ1480318543139.jpg","type":"image\/jpeg","tmp_name":"\/tmp\/phpe3zGok","error":0,"size":845941}}
POST: {"latitude":"0","longitude":"0","restaurant_id":"0","tags":"","city":"\u5317\u4eac","name":"\u0e1b\u0e31\u0e01\u0e01\u0e34\u0e48\u0e07"}
city: 北京
name: ปักกิ่ง
latitude: 0
longitude: 0
restaurant_id: 0

( ps:php 中,FILES 里有 tmp_name 为收到了文件,将临时文件从该路径中移动到指定目录便可保存文件,这里看到有 /tmp/phpe3zGok 临时文件,说明成功收到了文件) 将小程序预览到手机上,点击上传,但却出现了问题,如下所示:

详解微信小程序 wx.uploadFile 的编码坑

POST 数据为空, FILES 成功收到,而单独输出的$_POST数据出现乱码(中文和泰文部分),出现了溢出.

可以看到,非英文,数字的数据是乱码,而其它数据没有问题,显然是编码出现了问题,POST 数据输出为空,由于乱码导致了溢出使得格式错乱.

编码有问题,那么就尝试改变它的编码进行传输, uploadFile 的参数中加入

header{“chartset”:”utf-8”}
//或者 
header{"content-type":'application/x-www-form-urlencoded'}

但是都没有什么效果,依然是在微信小程序工具中有效,而手机真机预览的时候出现乱码.在看到这篇帖子 【新手跳坑指南《三十九》wx.uploadFile】 才知道header 里的数据在真机预览的时候是无效的,需要改到 formData 中,受到了启发,尝试将编码数据加入formData 中,但仅仅传输了数据,并没有改变编码.依然是小程序开发工具中调试成功,而真机预览出了问题,这个估计要微信团队来回答了。

知道 header 是个bug , 那么编码的操作暂时只能手动进行了,于是我将小程序段的数据都进行编码. 在 javascript 中,字符串编码函数是 encodeURI, 在小程序中尝试,也有该函数,所以我将小程序代码改为如下

wx.uploadFile({
      url: 'https://<upload_domain>/save',
      filePath:photoPath, //待上传的图片,由 chooseImage获得
      name:'food_image',
      formData: {
       latitude:encodeURI(0.0),
       longitude:encodeURI(0.0),
       restaurant_id:encodeURI(0),
       city:encodeURI('北京'),
       name:encodeURI('beijing') // 名称
      }, // HTTP 请求中其他额外的 form data
      success: function(res){
       console.log("addfood success",res);
      },
      fail: function(res) {
       console.log("addfood fail",res);
      },
     })
},

服务器端, php 进行 url 解码的函数是 urldecode

public function save(Request $request)
{
  error_log("FILES:" . json_encode($_FILES) . "\r\n", 3, "./logs/info.log");
  error_log("POST: " . json_encode($_POST) . "\r\n", 3, "./logs/info.log");
  error_log("city: " . urldecode($_POST["city"]) . "\r\n", 3, "./logs/info.log");
  error_log("name: " . urldecode($_POST["name"]) . "\r\n", 3, "./logs/info.log");
  error_log("latitude: " . urldecode($_POST["latitude"]) . "\r\n", 3, "./logs/info.log");
  error_log("longitude: " . urldecode($_POST["longitude"]) . "\r\n", 3, "./logs/info.log");
  error_log("restaurant_id: " . urldecode($_POST["restaurant_id"]) . "\r\n", 3, "./logs/info.log");
  error_log("tags: " . urldecode($_POST["city"]) . "\r\n", 3, "./logs/info.log");
  echo 'success';
}

再次测试,真机预览测试输出如下:

ILES:{"food_image":{"name":"jpeg","type":"image\/jpeg","tmp_name":"\/tmp\/php1svqDs","error":0,"size":9561}}
POST: {"restaurant_id":"0","tags":"","longitude":"0","latitude":"0","city":"%E5%8C%97%E4%BA%AC","name":"%E0%B8%9B%E0%B8%B1%E0%B8%81%E0%B8%81%E0%B8%B4%E0%B9%88%E0%B8%87"}
city: 北京
name: ปักกิ่ง
latitude: 0
longitude: 0
restaurant_id: 0

可以看到,所有数据都正常输出,其中POST 数据中 city 和 name未解码前是 urlencode 编码形式的数据,解码后正常输出.
至此,我想使用小程序上传带文件信息到服务器端算是调通了, 希望这个方法能对出现同样问题的同学有一定帮助。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
很酷的javascript loading效果代码
Jun 18 Javascript
js实现文本框中焦点在最后位置
Mar 04 Javascript
jQuery取消ajax请求的方法
Jun 09 Javascript
jQuery绑定事件on()与弹窗的简要概述
Apr 27 Javascript
基于BootStrap Metronic开发框架经验小结【九】实现Web页面内容的打印预览和保存操作
May 12 Javascript
Bootstrap基本插件学习笔记之轮播幻灯片(23)
Dec 08 Javascript
浅谈js基础数据类型和引用类型,深浅拷贝问题,以及内存分配问题
Sep 02 Javascript
ES6中let、const的区别及变量的解构赋值操作方法实例分析
Oct 15 Javascript
解决Echarts2竖直datazoom滑动后显示数据不全的问题
Jul 20 Javascript
vue 项目引入echarts 添加点击事件操作
Sep 09 Javascript
addEventListener()和removeEventListener()追加事件和删除追加事件
Dec 04 Javascript
jquery实现淡入淡出轮播图效果
Dec 13 jQuery
微信小程序侧边栏滑动特效(左右滑动)
Jan 23 #Javascript
微信小程序技巧之show内容展示,上传文件编码问题
Jan 23 #Javascript
Javascript同时声明一连串(多个)变量的方法
Jan 23 #Javascript
jQuery点击导航栏选中更换样式的实现代码
Jan 23 #Javascript
jQuery弹出层插件popShow(改进版)用法示例
Jan 23 #Javascript
JS判断指定dom元素是否在屏幕内的方法实例
Jan 23 #Javascript
jQuery弹出层插件popShow用法示例
Jan 23 #Javascript
You might like
MOTOROLA 摩托罗拉 MODEL 66-XI五灯中波收音机
2021/03/02 无线电
PHP中的加密功能
2006/10/09 PHP
PHP中extract()函数的妙用分析
2012/07/11 PHP
PHP大小写问题:函数名和类名不区分,变量名区分
2013/06/17 PHP
生成随机字符串和验证码的类的PHP实例
2013/12/24 PHP
php curl批处理实现可控并发异步操作示例
2018/05/09 PHP
浅析JavaScript中的CSS属性及命名规范
2013/11/28 Javascript
详解JavaScript的内置对象
2016/12/07 Javascript
jQuery中DOM节点的删除方法总结(超全面)
2017/01/22 Javascript
angular实现图片懒加载实例代码
2017/06/08 Javascript
Laravel整合Bootstrap 4的完整方案(推荐)
2018/01/25 Javascript
Vue之Vue.set动态新增对象属性方法
2018/02/23 Javascript
vue 如何使用递归组件
2020/10/23 Javascript
Python实现合并同一个文件夹下所有txt文件的方法示例
2018/04/26 Python
Python数据报表之Excel操作模块用法分析
2019/03/11 Python
详解用Python练习画个美队盾牌
2019/03/23 Python
详解Django 时间与时区设置问题
2019/07/23 Python
python利用openpyxl拆分多个工作表的工作簿的方法
2019/09/27 Python
python pycharm的安装及其使用
2019/10/11 Python
python爬虫添加请求头代码实例
2019/12/28 Python
python 线性回归分析模型检验标准--拟合优度详解
2020/02/24 Python
Python使用GitPython操作Git版本库的方法
2020/02/29 Python
Python reversed函数及使用方法解析
2020/03/17 Python
jupyter lab文件导出/下载方式
2020/04/22 Python
python 获取剪切板内容的两种方法
2020/11/28 Python
乌克兰香水和化妆品网站:Notino.ua
2018/03/26 全球购物
L*SPACE官网:比基尼、泳装和度假服装
2019/03/18 全球购物
世界领先的豪华床上用品供应商之一:Bedeck Home
2019/03/18 全球购物
大学考试作弊检讨书
2014/01/30 职场文书
安踏广告词改编版
2014/03/21 职场文书
支部书记四风问题自我剖析材料
2014/09/29 职场文书
科学发展观标语
2014/10/08 职场文书
业务员工作态度散漫检讨书
2014/11/02 职场文书
复兴之路展览观后感
2015/06/02 职场文书
党章学习心得体会2016
2016/01/14 职场文书
彩虹社八名人气艺人全新周边限时推出,性转女装男装一次拥有!
2022/04/01 日漫