微信小程序上传图片到七牛云

微信小程序上传图片到七牛云,小程序Webview嵌入H5上传图片&原生小程序上传图片

最近在帮朋友做微信小程序,没有选择mpvue,因为时间紧加上不熟悉,怕遇到坑不能快速处理,拖了进度,所以采用了原生小程序+webview的方式做了第一版。

小程序webview上传图片

因为涉及到H5,所以图片上传这块就用到了微信中的jssdk,

第一步是wx.config配置

前端代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
abp.services.app.wxAccess.getOfficialAccountJsdkConfig().done(function (data) {
if (data) {
var appId = data.appId;
var timestamp = data.timestamp;
var nonceStr = data.noncestr;
var signature = data.signature;
wx.config({
debug: false, //调试模式 当为tru时,开启调试模式
appId: appId,
timestamp: timestamp.toString(), //签名时间戳
nonceStr: nonceStr, //生成签名的随机串
signature: signature, //签名
jsApiList: ['chooseImage', 'uploadImage'],
success: function () {
alert("配置成功");
},
fail: function () {
alert("配置失败");
}
});
wx.ready(function () {
// 在这里调用 API
wx.checkJsApi({
jsApiList: [
'chooseImage',
'uploadImage'

],
success: function (res) {
//console.log(JSON.stringify(res));
}
});
});

wx.error(function(res){
alert(JSON.stringify(res));
});
}
});

后端代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/// <summary>
/// 获取公众号JsdkConfig
/// </summary>
/// <returns></returns>
public async Task<Dtos.GetOfficialAccountJsdkConfigOutput> GetOfficialAccountJsdkConfig()
{
var input = new Dtos.GetAccessInput
{
AppId = _appConfiguration["WechatOfficialAccount:AppId"],
Secret = _appConfiguration["WechatOfficialAccount:Secret"]
};

var noncestr = Guid.NewGuid().ToString("N");
var jsapi = await GetJsapiTicket(input);
//var timestamp = (DateTime.Now.Ticks - new DateTime(1970, 1, 1, 0, 0, 0, 0).Ticks) / 10000000;
var timestamp = new Helper.UnixTime().DateTimeToUnix(DateTime.Now);

//var url = Request.UrlReferrer.OriginalString;
var url = _iHttpContextAccessor.HttpContext.Request.Headers[Microsoft.Net.Http.Headers.HeaderNames.Referer].ToString();

var shaStr = $"jsapi_ticket={jsapi.Permit}&noncestr={noncestr}&timestamp={timestamp}&url={url}";

var signature = new Helper.Encrypt().Sha1Encrypt(shaStr);

return new Dtos.GetOfficialAccountJsdkConfigOutput
{
AppId = input.AppId,
Noncestr = noncestr,
Timestamp = timestamp,
Signature = signature
};
}

第二步就是调用jssdk

前端js代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
wx.chooseImage({
count: 9,
needResult: 1,
sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
success: function (data) {
//localIds = data.localIds[0]; // 返回选定照片的本地ID列表,localId可以作为img标签的src属性显示图片

for (var localId = 0; localId <= data.localIds.length - 1; localId++) {

if (isIOS) {

wx.getLocalImgData({
localId: data.localIds[localId], // 图片的localID
success: function (res) {

// var localData = res.localData; // localData是图片的base64数据,可以用img标签显示
//console.log(localData);


}
});
} else {

}
}

},
fail: function (res) {
alert(JSON.stringify(res));
//alterShowMessage("操作提示", JSON.stringify(res), "1", "确定", "", "", "");
}
});

jssdk中,如果是iOS的话,前端无法直接使用localIds资源id做展示,需要调用wx.getLocalImgData方法来获取图片的base64编码

提交前端选择的图片到服务端并由服务的上传到七牛云

前端部分代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
wx.uploadImage({ //获取图片媒体ID

localId: localIds[erp.common.idx].toString(), // 需要上传的图片的本地ID
isShowProgressTips: 1, // 默认为1,显示进度提示
success: function (res) { //获取成功
// 上传序号,上传一张 累计 +1
erp.common.idx++;
//存储图片媒体ID,用,号分割
// serverIds += res.serverId + ',';
erp.common.serverIdsArr.push(res.serverId);

if (erp.common.idx < localIds.length) { //本地图片ID 还没全部获取完图片媒体ID
//调用上传递归函数
erp.common.wxUploadImg(localIds, callback);
} else {
//上传序号归零
erp.common.idx = 0;
//服务器csrf 验证字符串,如果后端框架没开启csrf,则不需要
//alert(erp.common.serverIdsArr);
abp.services.app.wxAccess.uploadMediaToQiniu({
WxMediaIds: mediaIds
}).done(function (data) {

var imageUrl = [];
for (var index = 0; index <= data.qiniuFiles.length - 1; index++) {
imageUrl.push(data.qiniuFiles[index].qiniuUrl);
}
$.hideLoading();


callback && callback(imageUrl);


}).always(function(){
$.hideLoading();
});

//serverIds = '';
erp.common.serverIdsArr.length = 0;
return true;
}
},
fail: function (res) { //获取多媒体id失败 返回错误代码
alert("上传失败,msg:" + JSON.stringify(res));
}
});

后端部分代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/// <summary>
/// 上传文件到七牛
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
//[RemoteService(false)]
public async Task<Dtos.UploadMediaToQiniuOutput> UploadMediaToQiniu(Dtos.UploadMediaToQiniuInput input)
{
var output = new Dtos.UploadMediaToQiniuOutput();

if (input.WxMediaIds.Count > 0)
{
output.QiniuFiles = new System.Collections.Generic.List<Dtos.QiniuFile>();

var access_token = await GetOfficialAccountAccessToken();

var accessKey = _appConfiguration["Qny:qiniuyunAK"];
var secretKey = _appConfiguration["Qny:qiniuyunSK"];
var bucket = _appConfiguration["Qny:qiniuyunBucket"];
var prefixPath = _appConfiguration["Qny:prefixPath"];

var qiniuStorage = new Helper.QiniuStorage(accessKey, secretKey, bucket);

foreach (var mediaId in input.WxMediaIds)
{
var url = $"https://api.weixin.qq.com/cgi-bin/media/get?access_token={access_token.Permit}&media_id={mediaId}";
var fileKey = qiniuStorage.UploadStream(url);
var fileUrl = $"{prefixPath}/{fileKey}";

output.QiniuFiles.Add(new Dtos.QiniuFile { QiniuUrl = fileUrl, WxMediaId = mediaId });
}
}

return output;
}

原生小程序上传图片到七牛云

后面考虑到一些交互上面的问题,就把原来的webview方式改成了全原生的模式。采用原生的方式,在图片上传上面就好处理多了,只需要实现获取到七牛云用于上传的token,然后使用wx.uploadFile即可上传。
服务端获取token代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
/// <summary>
/// 获取七牛token
/// </summary>
/// <returns></returns>
public QiniuTokenOutputDto GetQiniuUpToken()
{
var accessKey = _appConfiguration["Qny:qiniuyunAK"];
var secretKey = _appConfiguration["Qny:qiniuyunSK"];
var bucket = _appConfiguration["Qny:qiniuyunBucket"];
var qiniuStorage = new Helper.QiniuStorage(accessKey, secretKey, bucket);
var output = new QiniuTokenOutputDto() { UpToken = qiniuStorage.CreateUploadToken() };
return output;
}

小程序端部分代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
1、获取token
2、调用小程序API,选择图片。
wx.chooseImage({
count: 9-this.data.cardImgList.length, //默认9
sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
sourceType: ['album', 'camera'], //从相册选择
success: (res) => {
res.tempFilePaths.forEach((item,index)=>{
that.upload2Qiniu(item);
});
}
});
}

/**
* 图片上传七牛云
*/
upload2Qiniu(tempFilePaths) {
let token = this.data.token;
var that = this;
wx.uploadFile({
url: 'https://up-z0.qiniup.com',
name: 'file',
filePath: tempFilePaths,
header: {
"Content-Type": "multipart/form-data"
},
formData: {
token: that.data.upToken,
},
success: function (res) {
let data = JSON.parse(res.data)

//data.hash图片的资源名,可直接通过域名加资源名访问
// to do ...
},
fail: function (res) {
console.log(res)
}
});
}

如果需要更详细的资料,那么就请自行百度or谷歌吧

#
You forgot to set the qrcode for Alipay. Please set it in _config.yml.
You forgot to set the qrcode for Wechat. Please set it in _config.yml.
You forgot to set the business and currency_code for Paypal. Please set it in _config.yml.
You forgot to set the url Patreon. Please set it in _config.yml.
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×