使用js直传oss阿里云存储文件,解决大文件上传服务器限制

本文介绍了如何使用JavaScript实现阿里云OSS的大文件直传,避免服务器成为瓶颈,提高上传速度并节省成本。通过设置Policy、签名等步骤,实现了文件直接从客户端上传到OSS,同时提供了前端页面的代码示例,包括上传进度显示和文件名处理。此方法优化了上传流程,提升了用户体验。
摘要由CSDN通过智能技术生成

使用js直传oss阿里云存储文件,解决大文件上传服务器限制

  • 每个OSS的用户都会用到上传服务。Web端常见的上传方法是用户在浏览器或App端上传文件到应用服务器,应用服务器再把文件上传到OSS。具体流程如下图所示。

在这里插入图片描述

客户短上传和数据直传到OSS相比,以上方法有三个缺点:

上传慢:用户数据需先上传到应用服务器,之后再上传到OSS。网络传输时间比直传到OSS多一倍。如果用户数据不通过应用服务器中转,而是直传到OSS,速度将大大提升。而且OSS采用BGP带宽,能保证各地各运营商之间的传输速度。
扩展性差:如果后续用户多了,应用服务器会成为瓶颈。
费用高:需要准备多台应用服务器。由于OSS上传流量是免费的,如果数据直传到OSS,不通过应用服务器,那么将能省下几台应用服务器。

上面可能废话有点多(阿里云官方解释),下面咱别写代码边解释!

在这里插入图片描述
以上oss直传js文件目录(后面可以下载!)

在这里插入图片描述

upload.js
accessid= '***';//阿里云oss accessid
accesskey= '***';//阿里云oss accesskey
host = 'https://***.oss-cn-beijing.aliyuncs.com';//Bucket 域名

g_dirname1 = ''
g_object_name1 = ''
g_object_name1_type = ''
now = timestamp = Date.parse(new Date()) / 1000;

var policyText1 = {
    "expiration": "2040-12-01T12:00:00.000Z", //设置该Policy的失效时间,超过这个失效时间之后,就没有办法通过这个policy上传文件了
    "conditions": [
        ["content-length-range", 0, 3048576000] // 设置上传文件的大小限制
    ]
};

var policyBase65 = Base64.encode(JSON.stringify(policyText1))
message1 = policyBase65
var bytes1 = Crypto.HMAC(Crypto.SHA1, message1, accesskey, { asBytes: true }) ;
var signature1 = Crypto.util.bytesToBase64(bytes1);
//设置成随机文件名
function check_object_radio1() {
    var tt = document.getElementsByName('myradio1');
    for (var i = 0; i < tt.length ; i++ )
    {
        if(tt[i].checked)
        {
            g_object_name1_type = tt[i].value;
            break;
        }
    }
}

//设置上传目录
function get_dirname1()
{
     dir = document.getElementById("dirname1").value;/前台做了一个输入框可以自己定义上传的目录
   // dir ='';
    if (dir != '' && dir.indexOf('/') != dir.length - 1)
    {
        dir = dir + '/'
    }
    g_dirname1 = dir
}

function random_string1(len) {
    len = len || 32;
    var chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678';
    var maxPos = chars.length;
    var pwd = '';
    for (i = 0; i < len; i++) {
        pwd += chars.charAt(Math.floor(Math.random() * maxPos));
    }
    return pwd;
}

function get_suffix1(filename) {
    pos = filename.lastIndexOf('.')
    suffix = ''
    if (pos != -1) {
        suffix = filename.substring(pos)
    }
    return suffix;
}

function calculate_object_name1(filename)
{
    if (g_object_name1_type == 'local_name')
    {
        g_object_name1 += "${filename}"
    }
    else if (g_object_name1_type == 'random_name')
    {
        suffix = get_suffix1(filename)
        g_object_name1 = g_dirname1 + random_string(10) + suffix
    }
    return ''
}

function get_uploaded_object_name1(filename)
{
    if (g_object_name1_type == 'local_name')
    {
        tmp_name = g_object_name1
        tmp_name = tmp_name.replace("${filename}", filename);
        return tmp_name
    }
    else if(g_object_name1_type == 'random_name')
    {
        return g_object_name1
    }
}

function set_upload_param1(up, filename, ret)
{
    g_object_name1 = g_dirname1;
    if (filename != '') {
        suffix = get_suffix1(filename)
        calculate_object_name1(filename)
    }
    new_multipart_params = {
        'key' : g_object_name1,//
        'policy': policyBase65,
        'OSSAccessKeyId': accessid,
        'success_action_status' : '200', //让服务端返回200,不然,默认会返回204
        'signature': signature1,
    };

    up.setOption({
        'url': host,
        'multipart_params': new_multipart_params
    });

    up.start();
}
var timer1,tryTime1,maxTry1=5,delay1=3000,num=0;
var uploader1 = new plupload.Uploader({//在文件里引入了一个 plupload前端上传插件
    runtimes : 'html5,flash,silverlight,html4',
    browse_button : 'selectfiles1',
    //multi_selection: false,
    container1: document.getElementById('container1'),
    flash_swf_url : 'lib/plupload-2.1.2/js/Moxie.swf',
    silverlight_xap_url : 'lib/plupload-2.1.2/js/Moxie.xap',
    url : 'http://oss.aliyuncs.com',
    init: {
        PostInit: function() {
            document.getElementById('ossfile1').innerHTML = '';
            document.getElementById('postfiles1').onclick = function() {
                set_upload_param1(uploader1, '', false);
                return false;
            };
        },

        FilesAdded: function(up, files) {//选择文件的信息
            plupload.each(files, function(file) {
                if(num==0){
                    document.getElementById('ossfile1').innerHTML += '<div id="' + file.id + '">' + file.name + ' (' + plupload.formatSize(file.size) + ')<b></b>'
                        +'<div class="progress"><div class="progress-bar" style="width:0%"></div></div>'
                        +'</div>';
                    num++;
                }else{
                    return false;
                }

            });
        },

        BeforeUpload: function(up, file) {
            check_object_radio1();
            get_dirname1();
            set_upload_param1(up, file.name, true);
        },

        UploadProgress: function(up, file) {
            var d = document.getElementById(file.id);
            d.getElementsByTagName('b')[0].innerHTML = '<span>' + file.percent + "%</span>";
            var prog = d.getElementsByTagName('div')[0];
            var progBar = prog.getElementsByTagName('div')[0]
            progBar.style.width= 5*file.percent+'px';
            progBar.setAttribute('aria-valuenow', file.percent);
        },

        FileUploaded: function(up, file, info) {
            if (info.status == 200)
            {
                tryTime1 = 0;//注释的地方是前端页面的一个视频播放组件
                // timer1 = setInterval(getDuration1, delay1);
                // videoElem = document.getElementById("au");
                // videoElem.innerHTML = '<source class="source" src="'+host+'/'+file.name+'" type="video/mp4">';
                // videoElem.play();
                $("#audioUrl").val(host+"/"+file.name+"");//返回的参数赋值到form之中
                document.getElementById(file.id).getElementsByTagName('b')[0].innerHTML = 'upload to oss success, object name:' + get_uploaded_object_name1(file.name);
            }
            else
            {
                document.getElementById(file.id).getElementsByTagName('b')[0].innerHTML = info.response;
            }
        },

        Error: function(up, err) {
            document.getElementById('console1').appendChild(document.createTextNode("\nError xml:" + err.response));
        }
    }
});

function getDuration1() {
    clearInterval(timer1);
    var hour = parseInt((au.duration)/3600);
    var minute = parseInt((au.duration%3600)/60);
    var second = Math.ceil(au.duration%60);
    $("#showByNones").show();
    $("#lengthTime1").val(hour+":"+minute+":"+second);
    var lengthTime = $("#lengthTime").val();
    if (lengthTime == null || lengthTime == "") {
        $("#showByNones2").show();
        $("#lengthTime").val(hour+":"+minute+":"+second);
    }
}
uploader1.init();

上传不仅仅上面一个文件还有lib文件夹里面的一些插件包

下面看下我自己写的前端页面

```html
div class="form-group">
                        <label class="col-sm-2 control-label">商品视频:</label>
                        <div class="col-sm-10">
                            <div style="display: none;">
                                <input type="radio" name="myradio1" value="local_name" checked=true/> 上传文件名字保持本地文件名字
                                <input type="radio" name="myradio1" value="random_name" /> 上传文件名字是随机文件名
                                上传到指定目录:<input type="text" id='dirname1' placeholder="如果不填,默认是上传到根目录" size=50>
                            </div>
                                <div>
<!--                                    <video height="240" object-fit="scale-down" controls="controls" muted="muted"  loop id="au">-->
<!--                                    </video>  这个是html的视频组件和upload.js里面对应起来即可-->

                            <h4>您所选择的文件:</h4>
                                    <div id="ossfile1" style="width: 200px;"></div>
                                    <div id="container1">
                                        <a id="selectfiles1" href="javascript:void(0);" class='btn'>选择文件</a>
                                        <a id="postfiles1" href="javascript:void(0);" class='btn'>开始上传</a>
                                    </div>
<!--                                    <pre id="console1"></pre>  里面是上传的回调信息-->
                                </div>

                        </div>
                    </div>
           <div class="form-group"  id="showByNones">
                <label class="col-sm-2 control-label">视频网络地址:</label>
                <div class="col-sm-10">
                    <input id="audioUrl" name="video" class="form-control"
                           type="text"  value="{$data.video|default=''}" readonly="readonly">
                </div>
            </div>

<!--       下面是引入的js      -->
<script type="text/javascript" src="__PUBLIC__/js/oss/lib/crypto1/crypto/crypto.js"></script>
<script type="text/javascript" src="__PUBLIC__/js/oss/lib/crypto1/hmac/hmac.js"></script>
<script type="text/javascript" src="__PUBLIC__/js/oss/lib/crypto1/sha1/sha1.js"></script>
<script type="text/javascript" src="__PUBLIC__/js/oss/lib/base64.js"></script>
<script type="text/javascript" src="__PUBLIC__/js/oss/lib/plupload-2.1.2/js/plupload.full.min.js"></script>
<script type="text/javascript" charset="utf-8" src="__PUBLIC__/js/oss/upload1.js?v=3.6"></script>

上传效果如下:
在这里插入图片描述

下载文件直接傻瓜式操作!!!

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
可以通过以下步骤实现: 1. 安装阿里云 Node.js SDK。 在 Node.js 环境下,可以使用阿里云 Node.js SDK 实现阿里云服务的访问。可以使用以下命令安装: ```bash npm install --save @alicloud/pop-core ``` 2. 在阿里云上创建 OSS 存储空间。 可以在阿里OSS 控制台中创建一个存储空间,用于存储上传的文件。 3. 在 Vue.js使用 Electron 的文件选择器选择文件夹。 可以使用 Electron 的 dialog 模块提供的 showOpenDialog 方法选择文件夹。具体可以参考以下代码: ```javascript const { dialog } = require('electron') dialog.showOpenDialog({ properties: ['openDirectory'] }).then(result => { console.log(result.filePaths) }).catch(err => { console.log(err) }) ``` 4. 遍历文件夹内的文件并上传到阿里OSS。 可以使用 Node.js 的 fs 模块遍历文件夹内的文件,并使用阿里云 Node.js SDK 将文件上传OSS 中。具体可以参考以下代码: ```javascript const fs = require('fs') const path = require('path') const Core = require('@alicloud/pop-core') const client = new Core({ accessKeyId: '<your-access-key-id>', accessKeySecret: '<your-access-key-secret>', endpoint: '<your-oss-endpoint>', apiVersion: '2013-10-15' }) // 遍历文件夹内的文件并上传到阿里OSS function uploadFilesToOSS(folderPath, bucketName) { fs.readdir(folderPath, (err, files) => { if (err) { console.log(err) return } files.forEach(file => { const filePath = path.join(folderPath, file) fs.stat(filePath, (err, stats) => { if (err) { console.log(err) return } if (stats.isFile()) { const fileName = path.basename(filePath) // 上传文件阿里OSS client.request('PutObject', { Bucket: bucketName, Key: fileName, Body: fs.createReadStream(filePath) }, (err, result) => { if (err) { console.log(err) return } console.log(`Uploaded ${fileName} to ${bucketName}`) }) } else if (stats.isDirectory()) { uploadFilesToOSS(filePath, bucketName) } }) }) }) } ``` 在以上代码中,`<your-access-key-id>` 和 `<your-access-key-secret>` 需要替换为你的阿里云访问密钥 ID 和访问密钥 Secret,`<your-oss-endpoint>` 需要替换为你的 OSS 服务的 endpoint,`uploadFilesToOSS` 方法需要传入文件夹路径和存储空间名称。 5. 在 Vue.js使用 Electron 的 IPC 模块与主进程通信。 在 Vue.js 中,可以使用 Electron 的 IPC 模块与主进程通信,将文件夹路径和存储空间名称传递给主进程。具体可以参考以下代码: ```javascript const { ipcRenderer } = require('electron') ipcRenderer.send('upload-files-to-oss', folderPath, bucketName) ``` 在以上代码中,`'upload-files-to-oss'` 是自定义的事件名称,`folderPath` 和 `bucketName` 分别是文件夹路径和存储空间名称。 6. 在 Electron 的主进程中监听 IPC 事件并调用上传方法。 在 Electron 的主进程中,可以监听 `'upload-files-to-oss'` 事件,并调用上传方法。具体可以参考以下代码: ```javascript const { ipcMain } = require('electron') ipcMain.on('upload-files-to-oss', (event, folderPath, bucketName) => { uploadFilesToOSS(folderPath, bucketName) }) ``` 至此,通过 electron 和 vue 将 Windows 下文件夹内文件传到阿里服务器的流程就完成了。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

孙奋斗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值