美文网首页
AliOSS前台上传文件-通过后台授权.md

AliOSS前台上传文件-通过后台授权.md

作者: 吃竹子的程序熊 | 来源:发表于2020-03-16 20:41 被阅读0次

封装代码

'use strict'//使用严格模式
const crypto = require('crypto');//加密模块

function Client(options) {
    if (!(this instanceof Client))
        return new Client(options);
    Client.validate(options);
    Client.initOptions(options);
}

Client.validate = (options,key)=> {
    if (Client.inited===true){ return;}
    if (!options||!options.accessKeySecret) {
        throw new Error('accessKeySecret是必需的!');
    }
    for (let key in options){
        if(options[key] === undefined){
            throw new Error('参数配置中出现了未定义数据:'+key);
        }
    }
    Client.inited=true;
};

Client.initOptions=(options)=>{
    Client.prototype.originData=options;
    let signData={
        conditions:[
            [
                "content-length-range",0,1048576000
            ]
        ]
    };
    //初始化policy有效期
    signData.expiration=new Date(Date.now()+(options.expires?options.expires:30)*1000);
    signData.conditions=Object.assign(signData.conditions,options.conditions?options.conditions:[]);
    Client.prototype.expirtion=signData.expiration;
    Client.prototype.signDate=JSON.stringify(signData);
    Client.prototype.key=options.accessKeySecret;

};
Client.prototype.signature=()=>{
    let signBase64=new Buffer(Client.prototype.signDate).toString("base64");
    let sha1= crypto.createHmac("SHA1",Client.prototype.key);
    let signature=sha1.update(signBase64).digest('base64');
    let result={
        originData:Client.prototype.originData,
        signatureData:Client.prototype.signDate,
        policy:signBase64,
        signature:signature,
        expirtion:Client.prototype.expirtion
    };
    return result;
};
module.exports=Client;

测试代码

const router=require('koa-router')();
const uuidv4 = require('uuid/v4');
const accessKeyId="";
const accessKeySecret="";
const host="";
const sign=require('../test/AliOSSSignUtil');//上面的生成签名的文件
router.get("/oss",async(ctx,next)=>{
    let res= new sign({accessKeySecret:accessKeySecret}).signature();
    let result={
        accessid:accessKeyId,//阿里OSS访问ID
        policy:res.policy,//base64转码后的约束信息
        signature:res.signature,//对policy使用访问密钥做SHA1加密的签名数据
        dir:"user-dir",//存储目录
        host:host,//阿里外网域名
        expire:res.expirtion,//该证书过期时间
        fileName:uuidv4()//文件名称
    };
    ctx.body=result;
    ctx.response.set("Access-Control-Allow-Origin","*");
    ctx.response.set("Access-Control-Allow-Credentials","true");
    ctx.response.set("Access-Control-Allow-Methods","GET, POST, DELETE, PUT");
    return;
});
module.exports=router;

测试页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>阿里文件上传测试页面</title>

</head>
<body>
<div style="width: 60%;margin-left: auto;margin-right: auto">
<div class="page-header success">
    <p class=""><h1>阿里OSS文件上传后台签名授权<small>for alioss</small></h1></p>
</div>
<div class="panel panel-warning">
    <div class="panel-heading">阿里OSS文件上传后台签名授权</div>
    <div class="panel-body">


                    <div class="form-group">
                        <label for="fileInput">上传文件:</label>
                        <form  id="fileForm" name="fileForm">
                        <input type="file" id="fileInput" class="btn btn-success">
                        </form>
                    </div>


              <div class="form-inline" style="margin-top: 20px">
                  <div class="btn-group" data-toggle="buttons-radio" id="div_fileChannel">
                      <label class="btn btn-success">
                          <input type="radio" name="radio_fileChannel" value="default" checked>使用默认文件名称
                      </label>
                      <label class="btn btn-default">
                          <input type="radio" name="radio_fileChannel" value="random">使用随机数生成名称
                      </label>
                      <label class="btn btn-warning">
                          <input type="radio" name="radio_fileChannel" value="custom">自定义文件名称
                      </label>
                  </div>
              </div>
        <div style="margin-top: 10px">
            <button id="submit" type="button" class="btn btn-primary" data-loading-text="Loading...">提交</button>
        </div>
    </div>
</div>
<div class="panel panel-success">
    <div class="panel-heading">返回结果</div>
    <div class="panel-body">
       <span id="resultContent">
           
       </span>
    </div>
</div>

</div>

<!--JavaScript-->
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
<script src="alioss.js"></script>
<!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">

<!-- 可选的 Bootstrap 主题文件(一般不用引入) -->
<link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">

<!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
<script src="https://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
</body>
</html>

测试页面对应的JS

/*
 * 获取文件名称的方法
 *
 */
var FileNameStrategy={

};

FileNameStrategy["default"]=()=>{
    return "";
};
FileNameStrategy["random"]=()=>{
    return "";
};
FileNameStrategy["custom"]=()=>{
    return "";
};
/**
 * 处理文件名称
 * @type {{process: (function(*))}}
 */
var FileNameProcess={
    process:(channel)=>{
        FileNameStrategy[channel?channel:"default"]();
    }
};
/**
 * 全局变量
 * @type {{Filename: *, hasFile: boolean, form: undefined, policy: undefined, expireTime: undefined, signDate: undefined}}
 * @private
 */
var _g_params={
    Filename:FileNameProcess.process(),//上传文件名称
    hasFile:false,//是否包含文件
    form:undefined,//提交的form表单数据
    policy:undefined,//授权证明
    expireTime:undefined,//超时时间
    signDate:undefined,//签名数据
    resultUrl:undefined//回调URL
};
/**
 *
 * 对外暴露的方法
 * @constructor
 */
const Client=function () {
    init();
};
//绑定各元素事件
let init=()=>{
    /*
     *  处理单选按钮,并修改全局变量值
     */
    let radio=$("input[name=radio_fileChannel]");
    radio.click(()=>{
        FileNameProcess.process($("input[name=radio_fileChannel]:checked").val());
    });
    /*
     * 处理文件处理
     */
    let fileContent=$("#fileInput");
    fileContent.on("change",()=>{
        //var form=new FormData($("#fileForm")[0][0].files[0]);
        _g_params.form=new FormData();
        _g_params.hasFile=true;
    });
    /*
     * 处理提交按钮
     *  先判断是有文件.
     *  提交时优先判断,是否缓存了policy,如果没有且超时,则请求后台,否则直接使用.
     *
     */
    let commit=$("#submit");
    commit.click(()=>{
        //校验文件
        if (_g_params.hasFile!=true||!_g_params.form){
            //提示错误

            //调用初始化方法
            return;
        }
        //校验是否有参数,如果没有,进行初始化
        if(!_g_params.expireTime||_g_params.expireTime<=new Date().getTime()){
            //请求后台接口,获取最新数据
            $.ajax({
                url:'http://192.168.1.160:3000/oss',
                type:"GET",
                async:false,
                success:function (data) {
                    _g_params.signDate=data;
                    _g_params.expireTime=data.expire;
                }
            });
        }
        //初始化form表单数据,进行数据请求
        formDataProcess();
        //请求
        $.ajax({
            url:_g_params.signDate.host,
            type:"POST",
            data:_g_params.form,
            processData:false, // 告诉jQuery不要去处理发送的数据
            contentType:false, // 告诉jQuery不要去设置Content-Type请求头
            cache: false,//设置为false将不会从浏览器缓存中加载请求信息
            async: false,//发送同步请求
            success:(data)=>{
                _g_params.resultUrl=$(data).find('Location').text();
                let imgContext="<span class='alert alert-info'>"+_g_params.resultUrl+"</span>";
                let imgTxt='<img class="img-responsive center-block" src="'+_g_params.resultUrl+'"/>';
                $("#resultContent").append(imgContext).append(imgTxt);
            },
            error:(data)=>{
                console.info(data)
            }

        });


    });

};
let formDataProcess=()=>{
    //初始化请求头
    let form=_g_params.form;
    let data=_g_params.signDate;
    form.append("key","user-dir/"+data.fileName+".jpeg");//文件名称
    form.append("policy",data.policy);//生成的数据
    form.append("OSSAccessKeyId",data.accessid);//id
    form.append("success_action_status",201);//选择201,获取返回内容
    form.append("Signature",data.signature);//签名
    form.append("file",$("#fileForm")[0][0].files[0]);//追加文件内容
    form.append('submit', "Upload to OSS");
};
$(()=>{
    new Client();
});

阿里云官方文档地址

相关文章

网友评论

      本文标题:AliOSS前台上传文件-通过后台授权.md

      本文链接:https://www.haomeiwen.com/subject/nvboehtx.html