├── .gitignore ├── LICENSE ├── README.md ├── examples ├── basics │ ├── README.md │ ├── package.json │ ├── photo.jpg │ └── upload.js └── client-to-server │ ├── README.md │ ├── app.js │ └── package.json ├── lib └── aliyun-oss-upload-stream.js ├── package.json └── test └── aliyun-oss-upload-stream.test.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .DS_Store 3 | config.js -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Berwin 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # aliyun-oss-upload-stream 2 | 3 | [](https://www.npmjs.com/package/aliyun-oss-upload-stream) 4 | [](https://www.npmjs.com/package/aliyun-oss-upload-stream) 5 | 6 | 用[Aliyun oss](https://github.com/aliyun-UED/aliyun-sdk-js) 的 Multipart upload API 实现的Node.js模块,通过stream的方式上传文件。 7 | 8 | ***官方指定Nodejs模块~*** 9 | 10 | ## 为什么使用stream? 11 | 12 | * 使用stream的方式上传文件可以很大程度上降低服务器内存开销。Aliyun官方SDK并没有对stream进行一个完美的封装,所以通常上传文件(Put Object)的流程是客户端上传文件到服务器,服务器把文件数据缓存到内存,等文件全部上传完毕后,一次性上传到Aliyun Oss服务。这样做一旦瞬间上传文件的请求过多,服务器的内存开销会直线上升。而使用stream的方式上传文件的流程是客户端在上传文件数据到服务器的过程中,服务器同时也在把文件数据往Aliyun Oss服务传送,而不需要在服务器上缓存文件数据。 13 | * 可以上传大文件,根据上传数据方式不同而不同, Put Object 方式 文件最大不能超过 5GB,而使用stream的方式,文件大小不能超过 48.8TB 14 | * 更快的速度,由于传统方式(Put Object方式)是客户端上传完毕文件后,统一上传到Aliyun Oss,而stream的方式基本上客户端上传完毕后,服务器已经把一大半的文件数据上传到Aliyun了,所以速度要快很多 15 | * 使用更简单,经过封装后,stream的方式使用起来非常的方便,1分钟就可以学会如何使用 16 | 17 | ## 例子 18 | 19 | ```javascript 20 | 21 | var ALY = require('aliyun-sdk'), 22 | fs = require('fs'); 23 | 24 | var ossStream = require('aliyun-oss-upload-stream')(new ALY.OSS({ 25 | accessKeyId: '在阿里云OSS申请的 accessKeyId', 26 | secretAccessKey: '在阿里云OSS申请的 secretAccessKey', 27 | endpoint: 'http://oss-cn-hangzhou.aliyuncs.com', 28 | apiVersion: '2013-10-15' 29 | })); 30 | 31 | var upload = ossStream.upload({ 32 | Bucket: 'Bucket', 33 | Key: 'Key (可以理解为文件名)' 34 | }); 35 | 36 | // 可选配置 37 | upload.minPartSize(1048576); // 1M,表示每块part大小至少大于1M 38 | 39 | upload.on('error', function (error) { 40 | console.log('error:', error); 41 | }); 42 | 43 | upload.on('part', function (part) { 44 | console.log('part:', part); 45 | }); 46 | 47 | upload.on('uploaded', function (details) { 48 | var s = (new Date() - startTime) / 1000; 49 | console.log('details:', details); 50 | console.log('Completed upload in %d seconds', s); 51 | }); 52 | 53 | var read = fs.createReadStream('./photo.jpg'); 54 | read.pipe(upload); 55 | 56 | var startTime = new Date(); 57 | ``` 58 | 59 | ## 使用 60 | 61 | ### 初始化 62 | 63 | ```javascript 64 | var ALY = require('aliyun-sdk'); 65 | 66 | var ossStream = require('aliyun-oss-upload-stream')(new ALY.OSS({ 67 | accessKeyId: '在阿里云OSS申请的 accessKeyId', 68 | secretAccessKey: '在阿里云OSS申请的 secretAccessKey', 69 | endpoint: 'http://oss-cn-hangzhou.aliyuncs.com', 70 | apiVersion: '2013-10-15' 71 | })); 72 | ``` 73 | 74 | ### 上传文件 75 | 76 | ```javascript 77 | var upload = ossStream.upload({ 78 | Bucket: 'Bucket-Name', 79 | Key: 'Key-Name' 80 | }); 81 | 82 | var read = fs.createReadStream('./photo.jpg'); 83 | read.pipe(upload); 84 | ``` 85 | 86 | ## 操作方法 87 | 88 | **upload.minPartSize** 89 | 90 | 用于调整每次上传一小块数据的大小,不得低于200KB,默认为200KB,如果经常上传大文件,建议用此方法把值调整大一些 91 | 92 | ``` 93 | var upload = ossStream.upload({ 94 | Bucket: 'Bucket-Name', 95 | Key: 'Key-Name' 96 | }); 97 | 98 | // 可选配置 99 | upload.minPartSize(1048576); // 1M,表示每块part大小至少大于1M 100 | 101 | var read = fs.createReadStream('./photo.jpg'); 102 | read.pipe(upload); 103 | ``` 104 | 105 | ## 事件 106 | 107 | **error** 108 | 109 | 当上传过程中发生错误,触发error事件,回调函数参数为错误信息 110 | 111 | ```javascript 112 | upload.on('error', function (error) { 113 | console.log('error:', error); 114 | }); 115 | ``` 116 | **part** 117 | 118 | 上传文件的过程中,会触发part事件,回调函数参数为当前分片的信息 119 | 120 | ```javascript 121 | upload.on('part', function (part) { 122 | console.log('part:', part); 123 | }); 124 | ``` 125 | 126 | **uploaded** 127 | 128 | 上传成功后触发该事件,回调函数参数为完整的 Object 129 | 130 | ```javascript 131 | upload.on('uploaded', function (details) { 132 | console.log('details:', details); 133 | }); 134 | 135 | ``` 136 | 137 | ## 安装 138 | 139 | ``` 140 | npm i --save aliyun-oss-upload-stream 141 | ``` 142 | 143 | PS: 如果大家使用过程中,发现什么问题或者需要添加什么功能,及时通知我哈~ 我会及时更新和发布新版本~ 144 | 145 | ## The MIT License (MIT) 146 | 147 | Copyright (c) 2015 Berwin 148 | 149 | Permission is hereby granted, free of charge, to any person obtaining a copy 150 | of this software and associated documentation files (the "Software"), to deal 151 | in the Software without restriction, including without limitation the rights 152 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 153 | copies of the Software, and to permit persons to whom the Software is 154 | furnished to do so, subject to the following conditions: 155 | 156 | The above copyright notice and this permission notice shall be included in all 157 | copies or substantial portions of the Software. 158 | 159 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 160 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 161 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 162 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 163 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 164 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 165 | SOFTWARE. 166 | -------------------------------------------------------------------------------- /examples/basics/README.md: -------------------------------------------------------------------------------- 1 | ## 修改配置信息 2 | 3 | ``` 4 | vi upload.js 5 | ``` 6 | 配置accessKeyId、secretAccessKey、endpoint和Bucket、Key 7 | 8 | ``` 9 | var ossStream = require('../lib/aliyun-oss-upload-stream.js')(new ALY.OSS({ 10 | accessKeyId: '在阿里云OSS申请的 accessKeyId', 11 | secretAccessKey: '在阿里云OSS申请的 secretAccessKey', 12 | endpoint: 'http://oss-cn-hangzhou.aliyuncs.com', 13 | apiVersion: '2013-10-15' 14 | })); 15 | 16 | var upload = ossStream.upload({ 17 | Bucket: 'Bucket-Name', 18 | Key: 'Key-Name' 19 | }); 20 | ``` 21 | 22 | ## 安装依赖 23 | 24 | ``` 25 | npm install 26 | ``` 27 | 28 | ## 运行 29 | 30 | ``` 31 | node upload.js 32 | ``` 33 | 34 | 也可以在配置完信息之后直接运行下面的命令 35 | 36 | ``` 37 | npm run upload 38 | ``` -------------------------------------------------------------------------------- /examples/basics/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "aliyun-oss-upload-stream-examples-simple", 3 | "version": "1.1.0", 4 | "description": "aliyun-oss-upload-stream examples simple", 5 | "main": "./upload.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "upload": "npm install && node upload.js" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "git+https://github.com/berwin/aliyun-oss-upload-stream.git" 13 | }, 14 | "keywords": [ 15 | "aliyun", 16 | "oss", 17 | "upload", 18 | "pipe", 19 | "stream" 20 | ], 21 | "author": "Berwin", 22 | "license": "MIT", 23 | "bugs": { 24 | "url": "https://github.com/berwin/aliyun-oss-upload-stream/issues" 25 | }, 26 | "homepage": "https://github.com/berwin/aliyun-oss-upload-stream#readme", 27 | "dependencies": { 28 | "aliyun-sdk": "^1.7.6" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /examples/basics/photo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/berwin/aliyun-oss-upload-stream/2ea237651ae2bdeb27ab9229205a695896a21023/examples/basics/photo.jpg -------------------------------------------------------------------------------- /examples/basics/upload.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var ALY = require('aliyun-sdk'), 4 | fs = require('fs'); 5 | 6 | var ossStream = require('../../lib/aliyun-oss-upload-stream.js')(new ALY.OSS({ 7 | accessKeyId: '在阿里云OSS申请的 accessKeyId', 8 | secretAccessKey: '在阿里云OSS申请的 secretAccessKey', 9 | endpoint: 'http://oss-cn-hangzhou.aliyuncs.com', 10 | apiVersion: '2013-10-15' 11 | })); 12 | 13 | var upload = ossStream.upload({ 14 | Bucket: 'Bucket-Name', 15 | Key: 'Key-Name' 16 | }); 17 | 18 | upload.on('error', function (error) { 19 | console.log('error:', error); 20 | }); 21 | 22 | upload.on('part', function (part) { 23 | console.log('part:', part); 24 | }); 25 | 26 | upload.on('uploaded', function (details) { 27 | var s = (new Date() - startTime) / 1000; 28 | console.log('details:', details); 29 | console.log('Completed upload in %d seconds', s); 30 | }); 31 | 32 | var read = fs.createReadStream('./photo.jpg'); 33 | read.pipe(upload); 34 | 35 | var startTime = new Date(); -------------------------------------------------------------------------------- /examples/client-to-server/README.md: -------------------------------------------------------------------------------- 1 | # 案例 2 | 3 | ## 修改配置信息 4 | 5 | ``` 6 | vim upload.js 7 | ``` 8 | 配置accessKeyId、secretAccessKey、endpoint和Bucket、Key 9 | 10 | ``` 11 | var ossStream = require('../lib/aliyun-oss-upload-stream.js')(new ALY.OSS({ 12 | accessKeyId: '在阿里云OSS申请的 accessKeyId', 13 | secretAccessKey: '在阿里云OSS申请的 secretAccessKey', 14 | endpoint: 'http://oss-cn-hangzhou.aliyuncs.com', 15 | apiVersion: '2013-10-15' 16 | })); 17 | 18 | var upload = ossStream.upload({ 19 | Bucket: 'Bucket-Name', 20 | Key: 'Key-Name' 21 | }); 22 | ``` 23 | 24 | ## 安装依赖 25 | 26 | ``` 27 | npm install 28 | ``` 29 | 30 | ## 运行 31 | 32 | ``` 33 | npm start 34 | ``` 35 | 36 | ## 访问 37 | 38 | ``` 39 | http://127.0.0.1:1995 40 | ``` 41 | 在页面上传图片,并查看终端,会在终端打印出上传相关信息 -------------------------------------------------------------------------------- /examples/client-to-server/app.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var http = require('http'); 4 | var Busboy = require('busboy'); 5 | var ALY = require('aliyun-sdk'); 6 | 7 | var ossStream = require('../../lib/aliyun-oss-upload-stream.js')(new ALY.OSS({ 8 | accessKeyId: '在阿里云OSS申请的 accessKeyId', 9 | secretAccessKey: '在阿里云OSS申请的 secretAccessKey', 10 | endpoint: 'http://oss-cn-hangzhou.aliyuncs.com', 11 | apiVersion: '2013-10-15' 12 | })); 13 | 14 | http.createServer(function(req, res) { 15 | if (req.method === 'POST') { 16 | var busboy = new Busboy({ headers: req.headers }); 17 | busboy.on('file', function(fieldname, file, filename, encoding, mimetype) { 18 | var upload = ossStream.upload({ 19 | Bucket: 'Bucket', 20 | Key: filename 21 | }); 22 | 23 | upload.on('error', function (error) { 24 | console.log('error:', error); 25 | }); 26 | 27 | upload.on('part', function (part) { 28 | console.log('part:', part); 29 | }); 30 | 31 | upload.on('uploaded', function (details) { 32 | console.log('details:', details); 33 | res.writeHead(303, { Connection: 'close', Location: '/' }); 34 | res.end(); 35 | }); 36 | 37 | file.pipe(upload); 38 | }); 39 | 40 | req.pipe(busboy); 41 | } else if (req.method === 'GET') { 42 | res.writeHead(200, { Connection: 'close' }); 43 | res.end('
\ 44 | \ 49 | '); 50 | } 51 | }).listen(1995, function() { 52 | console.log('Listening for requests'); 53 | }); -------------------------------------------------------------------------------- /examples/client-to-server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "aliyun-oss-upload-stream-examples-client-to-server", 3 | "version": "1.1.0", 4 | "description": "aliyun-oss-upload-stream examples client-to-server", 5 | "main": "./app.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "node app.js" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "git+https://github.com/berwin/aliyun-oss-upload-stream.git" 13 | }, 14 | "keywords": [ 15 | "aliyun", 16 | "oss", 17 | "upload", 18 | "pipe", 19 | "stream" 20 | ], 21 | "author": "Berwin", 22 | "license": "MIT", 23 | "bugs": { 24 | "url": "https://github.com/berwin/aliyun-oss-upload-stream/issues" 25 | }, 26 | "homepage": "https://github.com/berwin/aliyun-oss-upload-stream#readme", 27 | "dependencies": { 28 | "aliyun-sdk": "^1.9.1", 29 | "busboy": "^0.2.13" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /lib/aliyun-oss-upload-stream.js: -------------------------------------------------------------------------------- 1 | /**! 2 | * Aliyun-oss-upload-stream - lib/index.js 3 | * 4 | * 使用 stream 的方式上传文件 5 | * 6 | * Authors: 7 | * Berwin