MVC 微信公众号js-sdk上传图片至自己服务器

微信JS-SDK图片接口调用

本篇将使用.NET MVC介绍微信上传图片至自己服务器

微信公众平台js-sdk官方说明文档:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115

 

通过文档中微信JS-SDK的概述和JSSDK使用步骤,我们可以了解到微信提供给我们的接口是如何使用的。

 

图像接口

 

拍照或从手机相册中选图接口

wx.chooseImage({
count: 1, // 默认9
sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
success: function (res) {
var localIds = res.localIds; // 返回选定照片的本地ID列表,localId可以作为img标签的src属性显示图片
}
});

 

预览图片接口

wx.previewImage({
current: '', // 当前显示图片的http链接
urls: [] // 需要预览的图片http链接列表
});

 

上传图片接口

wx.uploadImage({
localId: '', // 需要上传的图片的本地ID,由chooseImage接口获得
isShowProgressTips: 1, // 默认为1,显示进度提示
success: function (res) {
var serverId = res.serverId; // 返回图片的服务器端ID
}
});

备注:上传图片有效期3天,可用微信多媒体接口下载图片到自己的服务器,此处获得的 serverId 即 media_id。

注意到微信只提供给我们上传图片后的ServerId,而已有效期只有3天,所以我们需要将临时素材上传至自己服务器中,serverId即为获取临时素材的MEDIA_ID

请求获取临时素材的接口地址为:

"https://api.weixin.qq.com/cgi-bin/media/get?access_token=ACCESS_TOKEN&media_id=MEDIA_ID"

现在直接前台代码

@model Senparc.Weixin.MP.Helpers.JsSdkUiPackage
@{
    ViewBag.Title = "微信图片接口Demo";
}

<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>微信图片接口Demo</title>
    <!--jQuery非JS-SDK必须-->
    <script src="~/scripts/jquery-1.10.2.min.js"></script>
    <script src="@(Request.Url.Scheme)://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
    <style type="text/css">
        button {
            width: 100px;
            height: auto;
            display: block;
            margin-bottom: 5px;
            font-size: 20px;
        }
    </style>
</head>
<body>
    <div>
        <button onclick="chooseImage();">选择图片</button>
        <button onclick="uploadImage();">图片上传</button>
        <button onclick="previewImage();">图片预览</button>
        选择的图片<div id="img"></div>
        上传的图片<div id="img2"></div>
    </div>

    <script type="text/javascript">
        wx.config({
            debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
            appId: '@Model.AppId', // 必填,公众号的唯一标识
            timestamp: '@Model.Timestamp', // 必填,生成签名的时间戳
            nonceStr: '@Model.NonceStr', // 必填,生成签名的随机串
            signature: '@Model.Signature',// 必填,签名
            jsApiList: [
                    'chooseImage',
                    'previewImage',
                    'uploadImage'
            ]
        });
        // 全局变量存储
        var images = {
            localIds: [],
            serverIds: []
        };
        //1.拍照、本地选图
        function chooseImage() {
            if (images.localIds.length == 9) {
                alert('最多允许选中9张图片');
                return;
            }
            else {
                wx.chooseImage({
                    count: 9 - images.localIds.length, // 默认9
                    sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
                    sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
                    success: function (res) {
                        $(function () {
                            $.each(res.localIds, function (i, n) {
                                images.localIds.push(n);
                                $("#img").append('<img src="' + n + '" style="width:70px; height:70px;margin-right:5px;"/>');
                            });
                        });
                    },
                    cancel: function () {
                        alert("已取消选择");
                    }
                });
            }
        }
        //2.上传图片
        var i = 0, length = 0;
        function uploadImage() {
            i = 0;
            length = 0;
            if (images.localIds.length == 0) {
                alert('请先使用选择图片按钮');
                return;
            }
            length = images.localIds.length;
            upload();
        }
        //递归调用的方法
        function upload() {
            wx.uploadImage({
                localId: images.localIds[i].toString(),
                success: function (res) {
                    images.serverIds.push(res.serverId.toString());
                },
                fail: function (res) {
                    alert(JSON.stringify(res));
                },
                complete: function (res) {
                    i++;
                    if (i < length) {
                        upload();
                    }
                    if (i == length) {
                        downloadImage(images.serverIds);
                    }
                }
            });
        }
        //下载图片的方法
        function downloadImage(serverIds) {
            $.get('@Url.Action("DownloadImageAsync")', { mediaArray: JSON.stringify(serverIds) }, function (data) {
                $.each(data, function (i, n) {
                    $("#img2").append('<img src="' + n + '" style="width:70px; height:70px;margin-right:5px;"/>');
                });
                //清空images
                images = {
                    localIds: [],
                    serverIds: []
                };
            }, "json");
        }

        //3.图片预览
        function previewImage() {
            var imgList = [
                  'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1516438929475&di=b957eeb994395ff6b99ad5a2aa0330f3&imgtype=0&src=http%3A%2F%2Fimg1.3lian.com%2Fimg013%2Fv4%2F11%2Fd%2F64.jpg',
                  'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1516438929477&di=ca86274989d88b420edf367a3f5c4ff3&imgtype=0&src=http%3A%2F%2Fimg2.3lian.com%2F2014%2Ff4%2F209%2Fd%2F23.jpg',
                  'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1516438929476&di=bb23036f8232b23f11d7f7226d91ca22&imgtype=0&src=http%3A%2F%2Fnews.shangqiuw.com%2Fupload%2FNews%2F2016-10-14%2F20161014111158277f960f.jpg'
            ];
            wx.previewImage({
                current: imgList[0],
                urls: imgList
            });
        }
        wx.error(function (res) {
            alert(res.errMsg);
        });
    </script>
</body>
</html>

 

 

接下来看控制器的代码

using Senparc.CO2NET.Extensions;
using Senparc.Weixin.MP.Helpers;
using System;
using System.Web.Mvc;
using Newtonsoft.Json;
using System.IO;
namespace WebSample.Controllers
{
    using Service;
    using System.Drawing;
    using System.Net.Http;
    using System.Threading.Tasks;
    using System.Collections.Generic;
    public class WeixinJSSDKController : Controller
    {
        //
        // GET: /WeixinJSSDK/
        public ActionResult Index()
        {
            //盛派开源封装的JSSDKHelper类,传递:AppId,Timestamp,NonceStr,Signature
            var jssdkUiPackage = JSSDKHelper.GetJsSdkUiPackage(Config.AppId, Config.AppSecret, Request.Url.AbsoluteUri);
            return View(jssdkUiPackage);
        }

        #region 上传图片下载至自己服务器的方法(异步请求)
        /// <summary>
        /// 上传图片下载至自己服务器的方法(异步请求)
        /// </summary>
        /// <param name="mediaArray"></param>
        /// <returns></returns>
        [HttpGet]
        public ActionResult DownloadImage(string mediaArray)
        {
            List<string> result = new List<string>();
            try
            {
                var mediaIdList = JsonConvert.DeserializeObject<List<string>>(mediaArray);
                string ip_port = Request.Url.Authority;
                foreach (var mediaId in mediaIdList)
                {
                    string path = string.Format("/upload/UploadImage/{0}/", DateTime.Now.ToString("yyyy-MM-dd"));
                    string fileName = Guid.NewGuid().ToString("n") + ".jpg";
                    string mapPath = Server.MapPath(path);
                    var dir = mapPath + fileName;
                    if (!Directory.Exists(mapPath))
                    {
                        Directory.CreateDirectory(mapPath);
                    }
                    using (MemoryStream ms = new MemoryStream())
                    {
                        //关键代码,senparc已经封装好了,这里使用的是media接口
                        Senparc.Weixin.MP.AdvancedAPIs.MediaApi.Get(Config.AppId, mediaId, ms);
                        using (FileStream fs = new FileStream(dir, FileMode.OpenOrCreate, FileAccess.ReadWrite))
                        {
                            ms.Position = 0;
                            byte[] buffer = new byte[5 * 1024 * 1024];
                            int bytesRead = 0;
                            while ((bytesRead = ms.Read(buffer, 0, buffer.Length)) != 0)
                            {
                                fs.Write(buffer, 0, bytesRead);
                            }
                            fs.Flush();
                        }
                        result.Add("https://" + ip_port + path + fileName);
                    }
                }
            }
            catch (Exception ex)
            {
                Senparc.Weixin.WeixinTrace.SendCustomLog("发生错误了", ex.Message);
            }
            return Json(result, JsonRequestBehavior.AllowGet);
        }

        /// <summary>
        /// 上传图片下载至自己服务器的方法(异步请求)
        /// </summary>
        /// <param name="mediaArray"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<ActionResult> DownloadImageAsync(string mediaArray)
        {
            List<string> result = new List<string>();
            try
            {
                var mediaIdList = JsonConvert.DeserializeObject<List<string>>(mediaArray);
                string ip_port = Request.Url.Authority;
                foreach (var mediaId in mediaIdList)
                {
                    string path = string.Format("/upload/UploadImage/{0}/", DateTime.Now.ToString("yyyy-MM-dd"));
                    string fileName = Guid.NewGuid().ToString("n") + ".jpg";
                    string mapPath = Server.MapPath(path);
                    var dir = mapPath + fileName;
                    if (!Directory.Exists(mapPath))
                    {
                        Directory.CreateDirectory(mapPath);
                    }
                    using (MemoryStream ms = new MemoryStream())
                    {
                        await Senparc.Weixin.MP.AdvancedAPIs.MediaApi.GetAsync(Config.AppId, mediaId, ms);
                        using (FileStream fs = new FileStream(dir, FileMode.OpenOrCreate, FileAccess.ReadWrite))
                        {
                            ms.Position = 0;
                            byte[] buffer = new byte[5 * 1024 * 1024];
                            int bytesRead = 0;
                            while ((bytesRead = ms.Read(buffer, 0, buffer.Length)) != 0)
                            {
                                fs.Write(buffer, 0, bytesRead);
                            }
                            fs.Flush();
                        }
                        result.Add("https://" + ip_port + path + fileName);
                    }
                }
            }
            catch (Exception ex)
            {
                Senparc.Weixin.WeixinTrace.SendCustomLog("发生错误了", ex.Message);
            }
            return Json(result, JsonRequestBehavior.AllowGet);
        }

        #endregion

    }
}

 

效果图为:

 

 

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 18
    评论
### 回答1: Spring Boot 是一个用于快速构建基于 Java 的应用程序的开源框架。微信公众号微信平台提供的一种服务,允许开发者在微信上创建自己的公众号,从而能够与用户进行交互、提供信息、进行营销等。 使用 Spring Boot 构建微信公众号意味着我们可以利用 Spring Boot 的优势快速开发和部署我们的公众号应用。Spring Boot 提供了丰富的特性和功能,例如自动配置、快速启动、内嵌 Servlet 容器等,使得我们能够以更高效的方式开发微信公众号应用程序。 在使用 Spring Boot 构建微信公众号时,我们可以利用微信公众平台提供的开发接口和 SDK,与微信服务器进行交互。该接口和 SDK 提供了丰富的功能,例如接收和回复消息、获取用户信息、上传素材、推送模板消息等。我们可以通过编写相应的代码,与微信服务器进行通信,并实现自定义的业务逻辑。 使用 Spring Boot 构建微信公众号还可以结合其他技术和框架,例如 Spring MVC、Spring Data JPA 等,来实现更复杂的功能。我们可以利用 Spring MVC 来处理微信服务器的请求,使用 Spring Data JPA 来操作数据库存储用户信息等。这些技术和框架的集成可以提高开发效率和代码质量。 总之,使用 Spring Boot 构建微信公众号能够帮助我们快速开发和部署应用,同时利用 Spring Boot 提供的特性和功能,使得开发过程更加高效和简化。 ### 回答2: Spring Boot是一个用于构建独立的、生产级的Spring应用程序的框架。它简化了Spring应用程序的配置和部署过程,并提供了许多默认配置,让开发者可以专注于业务逻辑的实现。 微信公众号是基于微信开放平台的一种应用,开发者可以通过微信公众号来与用户进行交互。使用微信公众号可以实现发送消息、接收消息、拉取用户信息等功能。通过集成Spring Boot框架,可以更加方便地开发和管理微信公众号应用。 使用Spring Boot开发微信公众号,可以通过Spring框架的依赖注入和控制反转等功能,更加灵活地管理公众号的业务逻辑和组件。开发者可以定义不同的Controller来处理用户的请求,并通过注解来实现自动装配和依赖管理。此外,Spring Boot还提供了许多自动配置的功能,使得开发者可以快速构建、测试和部署微信公众号应用。 Spring Boot还支持与微信公众平台的API进行交互,开发者可以通过SDK或自定义开发来实现微信公众号的各种功能。例如,可以使用SDK提供的API来发送消息、获取用户信息、创建菜单等。 总之,通过使用Spring Boot框架,开发者可以更加高效地开发和管理微信公众号应用,减少了繁琐的配置和部署过程,提高了开发效率和代码质量。 ### 回答3: Spring Boot 是一个基于 Spring 框架的开源项目,用于快速构建、运行和部署应用程序。微信公众号是基于微信平台的一种社交媒体营销工具,被广泛用于企业的宣传推广、客户互动等方面。那么,Spring Boot 如何与微信公众号结合呢? 首先,我们可以通过 Spring Boot 提供的 Web 应用程序开发框架,结合微信公众号的开发文档和接口,编写实现微信公众号功能的后端代码。通过使用 Spring Boot 的 MVC 架构,我们可以定义处理微信公众号各种请求的控制器,并利用 Spring 的依赖注入特性,调用微信公众号提供的接口实现相关功能。 其次,Spring Boot 提供了丰富的开箱即用的插件和组件,可以方便地集成第三方库和工具。我们可以利用 Spring Boot 的插件,快速集成微信公众号SDK 或 API,简化开发过程。同时,Spring Boot 还提供了很多自动配置选项,可以减少开发者的配置工作,提高开发效率。 另外,通过使用 Spring Boot 的自动化部署特性,我们可以将微信公众号的后端应用程序快速打包为可执行的 JAR 文件,并使用常用的部署或容器工具(如 Docker、Tomcat 等)进行部署和运行。这样,我们可以轻松地将微信公众号应用程序部署到云端,实现高可用性和扩展性。 总之,Spring Boot 提供了一个便捷、快速、可靠的开发框架,可以与微信公众号无缝结合,帮助开发者快速构建和部署功能丰富的微信公众号应用程序。无论是小型企业还是大型企业,利用 Spring Boot 可以极大地简化微信公众号的开发和运维工作,提升开发效率和用户体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值