获取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}
)