Node.js 服务端

使用 Node.js + Express.js 实现 服务端

const express = require("express");
const app = express();
const axios = require('axios'); app.set('port', process.env.PORT || 8082); // 静态资源目录,这里放在了根目录,生产环境不允许这样
app.use(express.static(__dirname)); // 启动一个端口为 8082 的服务器
app.listen(app.get('port'), () => {
console.log("http://localhost:" + app.get('port'));
});

准备 Base64、HMAC-SHA1、MD5 实现签名认证

详见:http://docs.upyun.com/api/authorization/#_5

const crypto = require("crypto");

// MD5
function MD5(value) {
return crypto
.createHash("md5")
.update(value)
.digest("hex");
} // Base64
function base64(value) {
return Buffer.from(value).toString("base64");
} // hmacsha1
function hmacsha1(secret, value) {
return crypto.createHmac('sha1', secret).update(value, 'utf-8').digest().toString('base64');
}

上传、删除接口

const date = new Date().toGMTString();
const bucketname = ""; // 空间名
const key = ""; // 操作员
const secret = ""; // 密码
const upyunUrl = 'http://v0.api.upyun.com/' // Upload
app.get("/api/token/upload", (req, res) => {
let fileName = (Math.random() * 100000000) >>> 0;
let expiration = ((Date.now() / 1000) >>> 0) + 30 * 60; // 请求的过期时间,UNIX UTC 时间戳,单位秒。建议设为 30 分钟 http://docs.upyun.com/api/form_api/
let method = "POST"; let policy = base64(
JSON.stringify({
bucket: bucketname,
// "save-key": "/" + fileName + "{.suffix}",
"save-key": "/{filename}{.suffix}",
expiration: expiration
})
); let authorization =
"UPYUN " +
key +
":" +
hmacsha1(MD5(secret), method + "&/" + bucketname + "&" + policy); res.json({
msg: "OK",
code: 200,
data: {
authorization: authorization,
policy: policy
}
});
}); // Delete
app.get('/api/token/del', (req, res) => {
let item = req.query.item;
let method = "DELETE"
let authorization = "UPYUN " +
key +
":" +
hmacsha1(MD5(secret), method + '&/' + bucketname + item + '&'+ date); axios({
url: upyunUrl + bucketname + item,
method: 'DELETE',
headers: {
'Authorization': authorization,
'Date': date
}
}).then(response => {
res.json({
msg: "OK",
code: 200,
data: {}
});
}).catch(err => {
console.log('err', err)
})
})

跨域接口调用

const cors = require('cors');

// CORS @see https://github.com/expressjs/cors
app.use(cors());

前端

前端使用 Vue.js 实现

引入 Bootstrap.css

<link rel="stylesheet" type="text/css" href="https://unpkg.com/bootstrap@4.1.3/dist/css/bootstrap.css">
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<!-- HTML -->
<div id="app">
<div class="card" style="margin: 50px auto; width: 300px;">
<div class="card-body">
<h5 class="card-title">UPYun Upload & Delete</h5>
<div class="card-text">
<div class="form-group">
<label for="file">Upload</label>
<input type="file" id="file" class="form-control-file" @change="onChange">
<div class="form-text text-muted">
<ul>
<li v-for="(item, index) in files">
{{item}} <a href="javascript:;" @click="onDel(item, index)">Del</a>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>

引入 Vue.js、Axios

<script src="https://unpkg.com/vue@2.5.17/dist/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

JS

const upUrl = 'http://v0.api.upyun.com/'  // +空间名,如:http://v0.api.upyun.com/yun-temp
const baseApi = 'http://localhost:8082/api/'
let uploadInput; let app = new Vue({
el: '#app',
data: {
files: []
},
methods: {
onChange: function () {
getToken(token => {
let formData = new FormData();
formData.append("file", uploadInput.files[0])
formData.append('policy', token.policy)
formData.append("authorization", token.authorization) axios({
method: 'POST',
url: upUrl,
data: formData
}).then(res => {
res = res || {} if (res.status !== 200) {
console.log('error')
return
} let data = res.data || {}
this.files.push(data.url)
alert('Success')
}).catch(err => {
console.log(err);
});
});
},
onDel: function (item, index) {
this.files.splice(index, 1)
axios.request({
url: baseApi + 'token/del',
method: 'GET',
params: {
item: encodeURI(item)
}
}).then(res => {
alert('Deleted.')
}).catch(err => {
console.log(err)
})
}
},
mounted () {
uploadInput = $('file')
}
}) // DOM 获取元素
function $ (el) {
return document.getElementById(el)
} // 获取 token
function getToken (fn) {
let token = window.localStorage.getItem('token');
token = JSON.parse(token) || {};
let nowTime = Date.now(); if (nowTime < token.expired && token.authorization && token.policy) {
fn(token)
return
} axios({
method: 'get',
url: baseApi + 'token/upload'
})
.then(res => {
let data = res.data || {}
data = data.data || {}
const authorization = data.authorization
const policy = data.policy
const expired = ((Date.now() / 1000) >>> 0) + 30 * 60; token = {
authorization,
policy,
expired
} fn(token)
window.localStorage.setItem('token', JSON.stringify(token))
});
}

项目源码

https://github.com/givebest/UPyun-upload-delete-node.js

转载请注明出处: https://blog.givebest.cn/other/2018/10/27/upyun-upload-delete-node.js.html

又拍云 Node.js 实现文件上传、删除的更多相关文章

  1. Node.js——获取文件上传进度

    https://juejin.im/post/5a77a46cf265da4e78327552?utm_medium=fe&utm_source=weixinqun

  2. node中间层实现文件上传

    一般情况下,前端的文件上传一般都是通过form表单的(<input type="file" />)来完成文件的上传,如果使用node中间层完成跨域,文件的上传就需要在n ...

  3. js获取文件上传进度

    js获取文件上传进度: <input name="file" id="FileUpload" type="file" /> &l ...

  4. Nodejs学习笔记(八)--- Node.js + Express 实现上传文件功能(felixge/node-formidable)

    目录 前言 formidable简介 创建项目并安装formidable 实现上传功能 运行结果 部分疑惑解析 写在之后 前言 前面讲了一个构建网站的示例,这次在此基础上再说说web的常规功能---- ...

  5. Nodejs学习笔记(八)—Node.js + Express 实现上传文件功能(felixge/node-formidable)

    前言 前面讲了一个构建网站的示例,这次在此基础上再说说web的常规功能----文件上传,示例以一个上传图片的功能为例子 上传功能命名用formidable实现,示例很简单! PS:最近比较忙,距上一次 ...

  6. node+express实现文件上传功能

    在进行node web开发时,我们可能经常遇到上传文件的问题,这一块如果我们没有经验,可能会遇到很多坑,下面我将跟大家分享一下,实现文件上传的一些方式. 一.node+express文件上传的常用方式 ...

  7. 基于node.js的websocket上传小功能

    一.node.js 在目录里新建index.js var ws = require("nodejs-websocket"); console.log("开始建立连接... ...

  8. JS大文件上传断点续传解决方案

    1 背景 用户本地有一份txt或者csv文件,无论是从业务数据库导出.还是其他途径获取,当需要使用蚂蚁的大数据分析工具进行数据加工.挖掘和共创应用的时候,首先要将本地文件上传至ODPS,普通的小文件通 ...

  9. JS大文件上传解决方案

    1 背景 用户本地有一份txt或者csv文件,无论是从业务数据库导出.还是其他途径获取,当需要使用蚂蚁的大数据分析工具进行数据加工.挖掘和共创应用的时候,首先要将本地文件上传至ODPS,普通的小文件通 ...

随机推荐

  1. Percentage&Last zero&Convert from char to float

    Percentage g_rate = wg_header-rate. condense g_rate. SHIFT g_rate RIGHT DELETING TRAILING '0'. REPLA ...

  2. [leetcode]45. Jump Game II青蛙跳(跳到终点最小步数)

    Given an array of non-negative integers, you are initially positioned at the first index of the arra ...

  3. freemaker超详细 讲解 配置

    一.FreeMarker简介 二.第一个FreeMark示例 2.1.新建一个Maven项目 2.2.添加依赖 2.3.添加存放模板的文件夹 2.4.添加模板 2.5.解析模板 2.6.运行结果 三. ...

  4. JSP的简单介绍

    什么是JSP? JSP全称是Java Server Pages,它和servle技术一样,都是SUN公司定义的一种用于开发动态web资源的技术. JSP这门技术的最大的特点在于,写jsp就像在写htm ...

  5. 受欢迎的牛[HAOI2006]

    --BZOJ1051 Description 每一头牛的愿望就是变成一头最受欢迎的牛.现在有N头牛,给你M对整数(A,B),表示牛A认为牛B受欢迎. 这 ​ 种关系是具有传递性的,如果A认为B受欢迎, ...

  6. merge and saveorupdate

    首先 saveOrUpdate返回void 也就是什么都不返回 而merge会返回一个对象 merge 在执行session.merge(a)代码后,a对象仍然不是持久化状态,a对象仍然不会被关联到S ...

  7. selenium实现淘宝的商品爬取

    一.问题 本次利用selenium自动化测试,完成对淘宝的爬取,这样可以避免一些反爬的措施,也是一种爬虫常用的手段.本次实战的难点: 1.如何利用selenium绕过淘宝的登录界面 2.获取淘宝的页面 ...

  8. 达里奥:典型的去杠杆化过程是怎么进行的zz

    猛人RayDalio的“三部曲”之三:关于去杠杆化的深入理解 作者系统地阐述了去杆杠化过程并深入探讨去杆杠化的运作机理,对我们理解当前全球乃至中国.即将或者已经面临的去杠杆化过程,应当能够带来一些帮助 ...

  9. [Err] 1418 - This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creator【s

    问题:执行创建函数的sql文件报错如下: [Err] 1418 - This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA ...

  10. 去掉input[type="number"]的默认样式

    input::-webkit-outer-spin-button,input::-webkit-inner-spin-button{ -webkit-appearance: none !importa ...