ruby on rails aliyun oss上传图片并预览

获取token

require 'json'
require 'base64'
require 'openssl'

module Aliyun
  class AliyunOssToken
    def initialize
      @access_key_id = Rails.configuration.application['ALIYUN_OSS_ACCESS_KEY_ID']
      @access_key_secret = Rails.configuration.application['ALIYUN_OSS_ACCESS_KEY_SECRET']
      @oss_host = Rails.configuration.application['ALIYUN_OSS_HOST']
      @expire_time = 30
    end

    def self.oss_token(updir)
      new().get_token(updir)
    end

    def get_token(updir) 
      updir = updir + '/'
      condition_arrary = [
        ['starts-with', '$key', updir]
      ]
      expire_syncpoint = Time.now.to_i + @expire_time
      expire = Time.at(expire_syncpoint).utc.iso8601()
      policy_dict = {
        conditions: condition_arrary,
        expiration: expire
      }
      policy = hash_to_jason(policy_dict)
      policy_encode = Base64.strict_encode64(policy).chomp
      h = OpenSSL::HMAC.digest('sha1', @access_key_secret, policy_encode)
      sign_result = Base64.strict_encode64(h).strip()

      token_dict = {
        accessid: @access_key_id,
        host: @oss_host,
        policy: policy_encode,
        signature: sign_result,
        expire: expire,
        callback: '',
        dir: updir
      }

      result = hash_to_jason(token_dict)
    end

    def hash_to_jason(source_hash)
      jason_string = source_hash.to_json;	
	
      jason_string.gsub!("\":[", "\": [")
      jason_string.gsub!("\",\"", "\", \"")
      jason_string.gsub!("],\"", "], \"")
      jason_string.gsub!("\":\"", "\": \"")
      jason_string
    end

  end
end

condition_arrary = [

['starts-with', '$key', updir]

]

这里这个key,我看了很久,文档有的地方又说是app secret, 其实就直接用'$key'就好,应该是要替换前端传递的key值

前端

# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://coffeescript.org/

send_request = (updir) ->
  xmlhttp = null
  if window.XMLHttpRequest?
    xmlhttp=new XMLHttpRequest()
  
  else if window.ActiveXObject?
    xmlhttp=new ActiveXObject("Microsoft.XMLHTTP")

  if xmlhttp?
    serverUrl = "/xxx?updir=#{updir}"
    xmlhttp.open( "GET", serverUrl, false )
    xmlhttp.send()
    return xmlhttp.responseText
  else 
    alert('Your browser does not support XMLHTTP')

# 生成文件名称
random_string = () ->
  chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678'
  pwd = ''
  for num in [1..28]
    pwd += chars.charAt(Math.floor(Math.random() * chars.length))
    
  return pwd

# 获取后缀并重新命名文件
get_new_file_name = (file) -> 
  pos = file.lastIndexOf('.')
  new_file_name = ''
  if (pos != -1)?
    file_name = random_string()
    suffix = file.substring(pos)
    new_file_name = file_name + suffix
  return new_file_name

# 获取签名
get_signature = (updir) ->
  sign_body = send_request(updir)
  signature_obj = eval ("(" + sign_body + ")")
  return signature_obj

#设置参数
set_upload_param = (file_key, signature_obj) -> 
  multipart_params = {
      'key' : file_key,
      'policy': signature_obj['policy'],
      'OSSAccessKeyId': signature_obj['accessid'], 
      'success_action_status' : '200', 
      'callback': '',
      'signature': signature_obj['signature'],
  }
  res = {
      'url': signature_obj['host'],
      'multipart_params': multipart_params
  }
  return res
  
# 图片列表模板
li_img_template = (url, file_name) ->
  return "<li><img src='#{url+file_name}' /><span class='delete-image'></span><p>#{file_name}</p></li>"
# 上传失败
fail_template = () ->
  return "<li>上传失败</li>"

$(document).on 'turbolinks:load', ->
  $('.media-picker').each ->
    el = $(this)
    # 长传按钮
    elbtn = el.find('.media-picker-button')
    # 上传路径
    upload_path = elbtn.attr('data-path')
    # 上传类型image video
    media_accept = elbtn.attr('data-accept')
    media_id = elbtn.attr('data-id')
    # 获取值
    input_field = el.find('input[type=hidden]')
    # 多图临时存储
    image_files = new Array()
    # 是否多文件上传
    multi_selection = false
    if elbtn.attr('data-multipe')?
      multi_selection = true
      # 是否有值
      #old_files = input_field.val()
      old_files = input_field.attr('value')
      if old_files != ''
        image_files = JSON.parse(old_files)
    # sign 签名
    signature_obj = '' 
    # 新文件名称
    new_file_name = ''
    uploader = new plupload.Uploader({
      runtimes : 'html5,flash,silverlight,html4',
      browse_button : elbtn.attr('data-id') + '_uploader', 
      multi_selection: multi_selection,
      auto_start: true,
      flash_swf_url : '../plupload/js/Moxie.swf',
      silverlight_xap_url : '../plupload/js/Moxie.xap',
      #url: '/backend/upload'
      
      filters: {
        mime_types: [
          {title : "Image files", extensions : "jpg,jpeg,gif,png,bmp"}
        ],
        max_file_size: '5mb', #最大只能上传5mb的文件
        prevent_duplicates: false, #不允许选取重复文件
      },
      
      init: {
        PostInit: () -> 

        BeforeUpload: (up, file) -> 
          signature_obj = get_signature(upload_path)
          file_name = get_new_file_name(file.name)
          new_file_name = signature_obj['dir'] + file_name
          params = set_upload_param(new_file_name, signature_obj)
          up.setOption(params)
        
        FilesAdded: (up) ->
          up.start()
          
        FileUploaded: (up, file, info) -> 
          if info.status == 200 
            file_name = new_file_name
            html = ''
            url = signature_obj['host'] + '/'
            if multi_selection
              image_files.push(file_name)
              #input_field.val(JSON.stringify(image_files))
              input_field.attr('value', JSON.stringify(image_files))
              for image in image_files 
                html += li_img_template(url, image)
            else 
              input_field.val(file_name)

              html += li_img_template(url, file_name)

            el.next('small').find('.image-list ul').html(html)

        Error: (up, err) ->
          html = fail_template()
          el.next('small').find('.image-list ul').html(html)
      }
    })
    uploader.init()

  # 删除
  $('.media-picker').each ->
    el = $(this)
    # 长传按钮
    elbtn = el.find('.media-picker-button')
    # images list
    images_list = el.next('small').find('.image-list ul')
    # 获取值
    input_field = el.find('input[type=hidden]')
    #old_files = input_field.val()
    old_files = input_field.attr('value')
    if elbtn.attr('data-multipe')?
      if old_files != ''
        image_files = JSON.parse(old_files)
    images_list.on 'click', '.delete-image', (event) =>
      current_target = $(event.currentTarget)
      current_image = current_target.next('p').html()
      current_target.parent().remove()
      # 是否多文件上传
      multi_selection = false
      if elbtn.attr('data-multipe')?
        image_files.splice(image_files.indexOf(current_image), 1)
        #input_field.val(JSON.stringify(image_files))
        input_field.attr('value', JSON.stringify(image_files))
      else 
        input_field.val('')
      
      $.post("/xxx", 
        { filename: current_image}
      )

    

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值