koa2使用阿里云oss的nodejs sdk实现上传图片

nodejs实现上传图片到阿里云,自然是写成接口形式比较方便,前端监听input file的改变,把file对象传入到formData中传入后端,不能直接传入file对象,后端需要接受formData,这里使用 formidable  中间件,其他中间件看到网上资料也可以实现,但是自己尝试之后无果。。。

其他中间件推荐:

connect-multiparty

multiparty

koa2-multiparty

自己实在理解不了具体如果拿这写中间件解析ajax传来的formData的方法,欢迎有相关demo的朋友共享,非常感谢!

最终找到了github上一个朋友写的,非常好用,这里贴一下代码:

nodejs文件:

const Koa = require("koa");
const fs = require("fs");
const router = require('koa-router')();
const formidable = require("formidable");
const app = new Koa();
const co = require('co');
const OSS = require('ali-oss');
const client = new OSS({
    region: 'oss-cn-qingdao',
    accessKeyId: 'LTAIBcDd9sXlrZV1',
    accessKeySecret: 'FAH7GFfzZ0F5EiR24IOYdHSzW9F6nh',
});

const home = (ctx, next) => {
    ctx.body = require("fs").readFileSync("./tpl/xiaoguan.html", "utf-8");
}

const upfile = async(ctx, next) => {
    var alioss_upfile = function() {
        return new Promise(function(resolve, reject) {
            var form = new formidable.IncomingForm();
            form.parse(ctx.req, function(err, fields, files) {
                if (err) { throw err; return; }
                // 文件名
                var date = new Date();
                var time = '' + date.getFullYear() + date.getMonth() + 1 + date.getDate();
                var filepath = time + '/' + date.getTime();
                var fileext = files.file.name.split('.');
                var upfile = files.file.path;
                var newfile = filepath + '.' + fileext[1];
                //ali-oss
                co(function*() {
                    client.useBucket('p-adm-test'); //自定义项
                    var result = yield client.put(newfile, upfile);
                    //var result = yield client.put(fields.store, new Buffer(fields.buffer));
                    console.log('文件上传成功!', result.url);
                    ctx.response.type = 'json';
                    ctx.response.body = result.url;
                    resolve(next());
                }).catch(function(err) {
                    console.log(err);
                });
            });
        });
    };
    await alioss_upfile();
};

router.get('/', home);

router.post('/upfile', upfile);

app.use(router.routes());

app.listen(3000);

html页面:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>阿里云OSS Nodejs Koa 上传示例</title>
    <script src="http://cdn.bootcss.com/jquery/1.11.1/jquery.min.js"></script>
</head>

<body>
    <div style="width:500px;padding:50px 0; border:1px solid #f2f2f2;text-align:center;">
        <img id="image" src="" width="131" />
        <br/>
        <form>
            <input type="file" id="file" name="file" />
        </form>
        <br/><br/>
        <span id="upfile" style="border:1px solid #ccc; background:#f2f2f2; font-size:14px; text-align:center;padding:3px 5px;">上传</span>
    </div>
    <script type="text/javascript">
        $(function() {
            var path, clip = $("#image"),
                FileReader = window.FileReader;
            $("#file").change(function() {
                if (FileReader) { //chrome浏览器处理  
                    var reader = new FileReader(),
                        file = this.files[0];
                    reader.onload = function(e) {
                        path = e.target.result;
                        //console.log('c', path);
                        clip.attr("src", path); //这里是把图片转成64位数据存入<img>中的src里  
                    };
                    reader.readAsDataURL(file);
                } else { //其他浏览器处理,火狐在这里就不写出来了,网上资料很多  
                    path = $(this).val();
                    if (/"\w\W"/.test(path)) {
                        path = path.slice(1, -1);
                    }
                    //console.log('f', path);
                    clip.attr("src", path);
                }
            });
        });
        //上传
        $('#upfile').click(function() {
            var form = document.forms[0];
            var formData = new FormData(form); //这里连带form里的其他参数也一起提交了,如果不需要提交其他参数可以直接FormData无参数的构造函数
            $.ajax({
                url: "/upfile",
                type: "POST",
                data: formData,
                dataType: "text",
                processData: false,
                contentType: false,
                success: function(data) {
                    console.log('imgurl:', data);
                },
                xhr: function() { //在jquery函数中直接使用ajax的XMLHttpRequest对象
                    var xhr = new XMLHttpRequest();
                    xhr.upload.addEventListener("progress", function(evt) {
                        if (evt.lengthComputable) {
                            var percentComplete = Math.round(evt.loaded * 100 / evt.total);
                            console.log("提交进度:" + percentComplete.toString() + '%'); //在控制台打印上传进度
                        }
                    }, false);
                    return xhr;
                }
            });
        });
    </script>
</body>

</html>

 formidable  中间件的fileds参数,是传入的formData的数据中出file对象以外的其他参数组合的对象,file参数是file对象,如果传入的file对象的名称是别的名称,一样可以识别。

获取当前file对象:

file.file(formData传入file对象的时候起的名称)

获取传入的其他对象:

fields.对象名称

这里我想用最新的es6的异步方式实现,求大家支招!我下边写的已经可以上传图片,但是就是不能返回到body数据。。。

exports.uploadFile = async (ctx,next) => {
let client = new OSS({
    region: 'oss-cn-qingdao',
    accessKeyId: '124214124',
    accessKeySecret: '1412414124',
    bucket: 'p-144-141244'
})


let form = new formidable.IncomingForm()
    form.parse(ctx.req, function (err, fields, files) {
        client.put(fields.path, files.file.path).then(function (val) {
            // console.log(val.res)
            ctx.body = {
                res: val.res.requestUrls
            }
        }).then(function (val) {
            // console.log(val.res)
            // console.log(val.content.toString())
            ctx.body = {
                res: '上传失败'
            }
        })
    })
}

猜你喜欢

转载自www.cnblogs.com/beileixinqing/p/9152113.html
今日推荐