微信小程序基于腾讯云对象存储的图片上传功能

在使用腾讯云对象存储之前,公司一直使用的是传统的FTP的上传模式,而随着用户量的不断增加,FTP所暴露出来的问题也越来越多,1.传输效率低,上传速度慢。2.时常有上传其他文件来攻击服务器,安全上得不到保障。所以我们在经过慎重考虑觉得使用第三方的云存储服务。

在最开始的时候我们在腾讯云与阿里云中选择,最终我们选择腾讯云,腾讯云在文件上传用时方面的性能比较突出,文件越大表现越好;在下载用时方面表现略优于阿里云;文件删除用时方面总体速度略逊于,但在不同大小文件删除用时上都比较稳定。当然这与我们主要用于开发微信小程序是有着密切的关系。

在我们酷客多小程序使用腾讯云对象存储的时候除了直接使用 API 接口外,COS 提供了丰富多样的 SDK 给我们使用,可是在他提供的SDK中并没有发现我们Asp.net相关的SDK

在一番百度和一顿操作终于让我找到啦!看到没,只能说隐藏的真深,而且还是历史版本的,但是不管怎么样我们还是找到啦

找到C#的SDK,下载下来 (附上C#版本SDK的下载地址 C# SDK github项目下载地址)然后按照SDK中提供的方法,就可以成功上传!

然而并没有这么简单,当我们使用SDK中的方法的时候发现,SDK中的方法只适用于,绝对路径地址的文件上传!也就是并不满足我们ASP.Net中使用文件域上传文件。此时我们只有对方法进行改造!

附上改造过后代码:

 /// <summary>
    /// 文件流上传
    /// 说明: 酷客多小程序
    /// 其中分片上传使用SliceUploadInit SliceUploadData SliceUploadFinihs
    /// </summary>
    /// <param name="bucketName">bucket名称</param>
    /// <param name="remotePath">远程文件路径</param>
    /// <param name="localPath">本地文件路径</param>
    /// <param name="parameterDic">参数Dictionary</param>
    /// <returns></returns>
    public string UploadFile(string bucketName, string remotePath, Stream file, string filename,Dictionary<string, string> parameterDic = null)
    {
      if (remotePath.EndsWith("/"))
      {
        return constructResult(ERRORCode.ERROR_CODE_PARAMETER_ERROE, "file path can not end with '/'");
      }
      string bizAttribute = "";
      if (parameterDic != null && parameterDic.ContainsKey(CosParameters.PARA_BIZ_ATTR))
        bizAttribute = parameterDic[CosParameters.PARA_BIZ_ATTR];
      int insertOnly = 1;
      if (parameterDic != null && parameterDic.ContainsKey(CosParameters.PARA_INSERT_ONLY))
      {
        try
        {
          insertOnly = Int32.Parse(parameterDic[CosParameters.PARA_INSERT_ONLY]);
        }
        catch (Exception e)
        {
          Console.WriteLine(e.Message);
          return constructResult(ERRORCode.ERROR_CODE_PARAMETER_ERROE, "parameter insertOnly value invalidate");
        }
      }
      return Upload(bucketName, remotePath, file, filename, bizAttribute, insertOnly);
    }

    /// <summary>
    /// 单个文件上传
    /// 说明: 酷客多小程序
    /// <param name="bucketName">bucket名称</param>
    /// <param name="remotePath">远程文件路径</param>
    /// <param name="localPath">本地文件路径</param>
    /// <param name="biz_attr">biz_attr属性</param>
    /// <param name="insertOnly">同名文件是否覆盖</param>
    /// <returns></returns>
    public string Upload(string bucketName, string remotePath, Stream file,string filename,
                 string bizAttribute = "", int insertOnly = 1)
    {

      var url = generateURL(bucketName, remotePath);
      var sha1 = SHA1.GetFileSHA1(file);
      var data = new Dictionary<string, object>();
      data.Add("op", "upload");
      data.Add("sha", sha1);
      data.Add("biz_attr", bizAttribute);
      data.Add("insertOnly", insertOnly);

      var expired = getExpiredTime();
      var sign = Sign.Signature(appId, secretId, secretKey, expired, bucketName);
      var header = new Dictionary<string, string>();
      header.Add("Authorization", sign);

      return httpRequest.SendRequest(url, ref data, HttpMethod.Post, ref header, timeOut, file, filename);
    }

    #region 直接上传文件流
    public string SendRequest(string url, ref Dictionary<string, object> data, HttpMethod requestMethod,
    ref Dictionary<string, string> header, int timeOut, Stream file,string filename, long offset = -1, int sliceSize = 0)
    {
      try
      {
        //Console.WriteLine("url:" + url);
        System.Net.ServicePointManager.Expect100Continue = false;
        if (requestMethod == HttpMethod.Get)
        {
          var paramStr = "";
          foreach (var key in data.Keys)
          {
            paramStr += string.Format("{0}={1}&", key, HttpUtility.UrlEncode(data[key].ToString()));
          }
          paramStr = paramStr.TrimEnd('&');
          url += (url.EndsWith("?") ? "&" : "?") + paramStr;
        }
        request = (HttpWebRequest)HttpWebRequest.Create(url);
        request.Accept = CosDefaultValue.ACCEPT;
        request.KeepAlive = true;
        request.UserAgent = CosDefaultValue.USER_AGENT_VERSION;
        request.Timeout = timeOut;
        foreach (var key in header.Keys)
        {
          if (key == "Content-Type")
          {
            request.ContentType = header[key];
          }
          else
          {
            request.Headers.Add(key, header[key]);
          }
        }
        if (requestMethod == HttpMethod.Post)
        {
          request.Method = requestMethod.ToString().ToUpper();
          var memStream = new MemoryStream();
          if (header.ContainsKey("Content-Type") && header["Content-Type"] == "application/json")
          {
            var json = JsonConvert.SerializeObject(data);
            var jsonByte = Encoding.GetEncoding("utf-8").GetBytes(json.ToString());
            memStream.Write(jsonByte, 0, jsonByte.Length);
          }
          else
          {
            var boundary = "---------------" + DateTime.Now.Ticks.ToString("x");
            var beginBoundary = Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");
            var endBoundary = Encoding.ASCII.GetBytes("\r\n--" + boundary + "--\r\n");
            request.ContentType = "multipart/form-data; boundary=" + boundary;
            var strBuf = new StringBuilder();
            foreach (var key in data.Keys)
            {
              strBuf.Append("\r\n--" + boundary + "\r\n");
              strBuf.Append("Content-Disposition: form-data; name=\"" + key + "\"\r\n\r\n");
              strBuf.Append(data[key].ToString());
            }
            var paramsByte = Encoding.GetEncoding("utf-8").GetBytes(strBuf.ToString());
            memStream.Write(paramsByte, 0, paramsByte.Length);
            memStream.Write(beginBoundary, 0, beginBoundary.Length);
            var fileStream = file;
            const string filePartHeader =
              "Content-Disposition: form-data; name=\"fileContent\"; filename=\"{0}\"\r\n" +
              "Content-Type: application/octet-stream\r\n\r\n";
            var headerText = string.Format(filePartHeader, filename);
            var headerbytes = Encoding.UTF8.GetBytes(headerText);
            memStream.Write(headerbytes, 0, headerbytes.Length);
            if (offset == -1)
            {
              var buffer = new byte[1024];
              int bytesRead;
              while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
              {
                memStream.Write(buffer, 0, bytesRead);
              }
            }
            else
            {
              var buffer = new byte[sliceSize];
              int bytesRead;
              fileStream.Seek(offset, SeekOrigin.Begin);
              bytesRead = fileStream.Read(buffer, 0, buffer.Length);
              memStream.Write(buffer, 0, bytesRead);
            }
            fileStream.Close();
            memStream.Write(endBoundary, 0, endBoundary.Length);
          }
          request.ContentLength = memStream.Length;
          var requestStream = request.GetRequestStream();
          memStream.Position = 0;
          var tempBuffer = new byte[memStream.Length];
          memStream.Read(tempBuffer, 0, tempBuffer.Length);
          memStream.Close();
          requestStream.Write(tempBuffer, 0, tempBuffer.Length);
          requestStream.Close();
          //Console.WriteLine(strBuf.ToString());
        }
        //Console.WriteLine(request.ContentType.ToString());
        var response = request.GetResponse();
        using (var s = response.GetResponseStream())
        {
          var reader = new StreamReader(s, Encoding.UTF8);
          return reader.ReadToEnd();
        }
      }
      catch (WebException we)
      {
        if (we.Status == WebExceptionStatus.ProtocolError)
        {
          using (var s = we.Response.GetResponseStream())
          {
            var reader = new StreamReader(s, Encoding.UTF8);
            return reader.ReadToEnd();
          }
        }
        else
        {
          throw we;
        }
      }
      catch (Exception e)
      {
        throw e;
      }
    }

使用上面改造过后的方法直接传入文件流即可通过文本域的方式上传文件到腾讯云上面去!

总结

以上所述是小编给大家介绍的微信小程序基于腾讯云对象存储的图片上传功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!

您可能感兴趣的文章:

  • 微信小程序实现图片上传功能实例(前端+PHP后端)
  • 微信小程序实现图片上传、删除和预览功能的方法
  • 微信小程序多张图片上传功能
  • 微信小程序 图片上传实例详解
  • 微信小程序开发之从相册获取图片 使用相机拍照 本地图片上传
  • 微信小程序开发(二)图片上传+服务端接收详解
  • 微信小程序教程之本地图片上传(leancloud)实例详解
时间: 2018-03-17

微信小程序实现图片上传、删除和预览功能的方法

本文实例讲述了微信小程序实现图片上传.删除和预览功能的方法.分享给大家供大家参考,具体如下: 这里主要介绍一下微信小程序的图片上传图片删除和图片预览 布局 <view class="img-v"> <view class="img" wx:for="{{imgs}}" wx:for-item="item" wx:key="*this"> <image src="{{i

微信小程序实现图片上传功能实例(前端+PHP后端)

前言 几乎每个程序都需要用到图片.下面就来给大家介绍前端+PHP后端实现微信小程序实现图片上传功能,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 方法如下: 一.wxml文件 <text>上传图片</text> <view> <button bindtap="uploadimg">点击选择上传图</button> </view> <image src='{{source}}' style=

微信小程序多张图片上传功能

微信小程序上传图片每次只能上传一张,所有很多朋友就会问想要多张图片上传怎么办? 首先,我们来看一看wx.chooseImage(object)和wx.uploadFile(OBJECT)这两个个api 示例代码是这样的: wx.chooseImage({ success: function(res) { var tempFilePaths = res.tempFilePaths wx.uploadFile({ url: 'http://example.weixin.qq.com/upload',

微信小程序教程之本地图片上传(leancloud)实例详解

微信小程序 leancloud --本地图片上传 由于本站最近学习微信小程序的知识,这里记录下微信小程序实现本地上传的功能实现方法,以下是网上找的资料,大家看下. 将本地图片上传至leancloud后台. 获取本地图片或者拍照,我在上一篇博文中写过.这里就不说了.我的博客 直接上代码: 1.index.js //index.js //获取应用实例 var app = getApp() const AV = require('../../utils/av-weapp.js'); Page({ da

微信小程序 图片上传实例详解

一.了解wx.chooseImage(OBJECT) 二.代码编程 在pages文件里面创建uploadimg文件夹 1.编写页面结构:uploadimg.wxml <view class="container" style="padding:1rem;"> <button type="primary"bindtap="chooseimage">获取图片</button> <image

微信小程序开发之从相册获取图片 使用相机拍照 本地图片上传

今天遇到微信小程序的用户头像设置功能,做笔记. 先上gif: 再上代码: 小demo,代码很简单. 1.index.wxml <!--index.wxml--> <button style="margin:30rpx;" bindtap="chooseimage">获取图片</button> <image src="{{tempFilePaths }}" mode="aspecFill"

微信小程序开发(二)图片上传+服务端接收详解

这次介绍下小程序当中常用的图片上传. 前几天做了图片上传功能,被坑了一下.接下来我们来看一下微信的上传api. 这里的filePath就是图片的存储路径,类型居然是个String,也就是 只能每次传一张图片,我以前的接口都是接收一个array,我本人又是一个半吊子的PHP,只能自己去改接收图片的接口. 看一下页面效果图 一个很常见的修改头像效果,选择图片(拍照),然后上传. 下面就是贴代码了 首先是小程序的wxml代码 <view class="xd-container">

微信小程序实现多图上传

本文实例为大家分享了微信小程序实现多图上传的具体代码,供大家参考,具体内容如下 前言 纯属是笔记,复用性太高,前后端封装的上传的多图方法 看一下效果图 index.html <view class="imgs"> <block wx:for="{{ imgs }}" wx:key="{{ index }}"> <view class="img-box"> <image src=&quo

微信小程序实现多张图片上传功能

本文实例为大家分享了微信小程序实现多张图片上传的具体代码,供大家参考,具体内容如下 Page({ /** * 页面的初始数据 */ data: { pics: [], count: 9, //上传图片最大数量 // showImgUrl: "", //路径拼接,一般上传返回的都是文件名, uploadImgUrl: 'https://xxx/UploadHandler.ashx', //图片的上传的路径 detailPics: [], //上传的结果图片集合 }, selectimag

微信小程序 wx.uploadFile无法上传解决办法

微信小程序 wx.uploadFile无法上传解决办法 微信安卓客户端无法使用wx.uploadFile上传文件的问题有不少开发者都遇到. 我也因为一直不能解决,硬着头皮提交审核最后被拒(抱着审核者最好用iOS检测的心态,不巧审核我应用的用的是安卓),才尝试使用第三方的手段解决. 最终我是用了七牛第三方存储的方式,将文件直接上传至七牛的储存的空间上再回调使用. 当然像又拍云,万象优图这些第三方存储源都可以采用这种思路. 首先是将七牛的https上传域名放进小程序的域名名单中. 这里我使用的是七牛

微信小程序封装多张图片上传api代码实例

这篇文章主要介绍了微信小程序封装多张图片上传api代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 代码如下 export default class Upload{ constructor(object) { this.obj = { count:1, sizeType:['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有 sourceType:['album','camera'], //

微信小程序 ES6Promise.all批量上传文件实现代码

微信小程序 ES6Promise.all批量上传文件实现代码 客户端 Page({ onLoad: function() { wx.chooseImage({ count: 9, success: function({ tempFilePaths }) { var promise = Promise.all(tempFilePaths.map((tempFilePath, index) => { return new Promise(function(resolve, reject) { wx.

使用python&nbsp;flask框架开发图片上传接口的案例详解

python版本:3.6+ 需要模块:flask,pillow 需求:开发一个支持多格式图片上传的接口,并且将图片压缩,支持在线预览图片. 目录结构: app.py编辑内容: from flask import Flask, request, Response, render_template from werkzeug.utils import secure_filename import os import uuid from PIL import Image, ExifTags app =

微信小程序之高德地图多点路线规划过程示例详解

调用 如何调用高德api? 高德官方给出的https://lbs.amap.com/api/wx/summary/开放文档比较详细: 第一步,注册高德开发者 第二部,去控制台创建应用 即点击右上角的控制平台创建应用 创建应用绑定服务记得选择微信小程序:同时在https://lbs.amap.com/api/wx/gettingstarted中下载开发包 第三步,登陆微信公众平台在开发设置中将高德域名配置上 https://restapi.amap.com 第四步,打开微信开发者工具,打开微信小程

微信小程序:数据存储、传值、取值详解

小程序界面传值 父级界面:A界面 子级界面:B界面 一.url传值 详细的配置参数可以查看组件导航:navigator,这里不再做过多的解释. 1. 正向传值:A界面 –>B界面 用 navigator标签或 wx.navigator传值,A界面向B界面传id值 A界面获取id值传向B界面如果需要传多个参数, 用 & 链接即可 // 方法一:navigator标签传值 <navigator url="/page/index/index?id=110" >传值&

微信小程序中button组件的边框设置的实例详解

微信小程序中button组件的边框设置的实例详解 button的边框是用:after方式实现的,用户如果在button上定义边框会出现两条线,需用:after的方式去覆盖默认值. 如果设置了Button的背景色,没有用:after设置边框的颜色,则button的四个角会出现模糊的尖角.如下图所示: 如上图四个角会模糊..wxss代码如下: .clickEncryptBtn{ width:130px; border-radius: 3px; margin:20px auto; padding-to