nodejs express圖片上傳先後端配置講解

nodejs圖片上傳

nodejs通常開發網站基本都用express框架,本文也主要以express爲例,講解如何上傳圖片;
express自己沒有上傳圖片功能;通常都是集成相應的模塊;經常使用的有multer中間件和formidable中間件,前一個我配置的時候老是出錯,因此pass;此處主要演示formidable的用法;javascript

首先前端頁面配置,無非兩種,

-表單提交;
-ajax提交;
表單提交代碼以下css

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<form action="/uploader" method="post" enctype="multipart/form-data">
    <!--注意此處的name和後端files的屬性對應-->
    <input type="file" name="fulAvatar">
    <input type="submit">
</form>
</body>
</html>

這裏注意表單的enctype屬性必定要是:multipart/form-data
<input type="file" name="fulAvatar">別忘了name屬性;
這是html文檔的講解:html

定義和用法
enctype 屬性規定在發送到服務器以前應該如何對錶單數據進行編碼。前端

默認地,表單數據會編碼爲 "application/x-www-form-urlencoded"。就是說,在發送到服務器以前,全部字符都會進行編碼(空格轉換爲 "+" 加號,特殊符號轉換爲 ASCII HEX 值)。html5

Alt text

ajax提交:java

<!DOCTYPE>
<html>
<head>
    <title> formdata file jquery ajax upload</title>
</head>

<body>
<img id="showImg" src="" alt="">

<form role="form" id="myForm" action="http://v0.api.upyun.com/xxx" method="post" enctype="multipart/form-data">

    <input type="hidden" name="policy" value="">
    <input type="hidden" name="signature" value="">

    <div class="form-group">
        <label class="col-sm-2 control-label">說明:</label>

        <div class="col-sm-10">
            <p class="form-control-static ">ajax 文件上傳 。</p>
        </div>
    </div>
    <div class="form-group">
        <label for="url" class="col-sm-2 control-label"><s>*</s>圖片選擇:</label>

        <div class="col-sm-7">
            <input type="file" name="fulAvatar" id="file_upload" value=""
                   class="form-control" placeholder="圖片地址" onchange="uploadByForm();">
        </div>
    </div>

    <div class="form-group">
        <div class="col-sm-offset-2 col-sm-7">

            <a id="btnAjax" onclick=>Ajax上傳</a>
        </div>
    </div>
</form>

<script src="http://cdn.bootcss.com/jquery/1.11.1/jquery.min.js"></script>
<script type="text/javascript">

    /**
     * ajax 上傳。
     */
    function uploadByForm() {
        //用form 表單直接 構造formData 對象; 就不須要下面的append 方法來爲表單進行賦值了。
        var formData = new FormData($("#myForm")[0]);
        var url = "http://localhost:3000/uploader";
        $.ajax({
            url: url,
            type: 'POST',
            data: formData,

            /**
             * 必須false纔會避開jQuery對 formdata 的默認處理
             * XMLHttpRequest會對 formdata 進行正確的處理
             */
            processData: false,
            /**
             *必須false纔會自動加上正確的Content-Type
             */
            contentType: false,
            success: function (responseStr) {
                alert(responseStr.newPath);
                $("img").attr({"src": responseStr.newPath}).prependTo($("body"));
            },
            error: function (responseStr) {
                alert(responseStr.newPath);
            }
        });
    }

</script>
</body>
</html>

ajax上傳主要用的是Jquery;這一塊只是知道這麼用;配置ajax的時候processDatacontentType都設置爲false;
還有此處用了HTML5的一個新特性;FormData;
用法以下:new FormData($("#myForm")[0]);node

關於ajax這一塊我作了個嘗試,就是不用html5的FormData,而是直接用$("file_upload").val()去取文件表單的值,而後經過ajax傳遞,結果不是很理想;

將這坨數據傳到後端就能夠了;jquery

前端頁面演示完了;下面是後端代碼演示:

var express = require('express');
var router = express.Router();
var formidable = require('formidable'),
    fs = require('fs'),
    TITLE = 'formidable上傳示例',
    AVATAR_UPLOAD_FOLDER = '/avatar/',
    domain = "http://localhost:3000";

/* 圖片上傳路由 */
router.post('/uploader', function(req, res) {

  var form = new formidable.IncomingForm();   //建立上傳表單
  form.encoding = 'utf-8';        //設置編輯
  form.uploadDir = 'public' + AVATAR_UPLOAD_FOLDER;     //設置上傳目錄
  form.keepExtensions = true;     //保留後綴
  form.maxFieldsSize = 2 * 1024 * 1024;   //文件大小

  form.parse(req, function(err, fields, files) {

    if (err) {
      res.locals.error = err;
      res.render('index', { title: TITLE });
      return;
    }
    console.log(files);

    var extName = '';  //後綴名
    switch (files.fulAvatar.type) {
      case 'image/pjpeg':
        extName = 'jpg';
        break;
      case 'image/jpeg':
        extName = 'jpg';
        break;
      case 'image/png':
        extName = 'png';
        break;
      case 'image/x-png':
        extName = 'png';
        break;
    }

    if(extName.length == 0){
      res.locals.error = '只支持png和jpg格式圖片';
      res.render('index', { title: TITLE });
      return;
    }

    var avatarName = Math.random() + '.' + extName;
    //圖片寫入地址;
    var newPath = form.uploadDir + avatarName;
    //顯示地址;
    var showUrl = domain + AVATAR_UPLOAD_FOLDER + avatarName;
    console.log("newPath",newPath);
    fs.renameSync(files.fulAvatar.path, newPath);  //重命名
    res.json({
      "newPath":showUrl
    });
  });
});
module.exports = router;

圖片傳到後端其實就是一段2進制字符串,保存在內存中,須要用到fs模塊讀取後再寫入到新的目錄;打印filesajax

{ fulAvatar: 
   File {
     domain: null,
     _events: {},
     _eventsCount: 0,
     _maxListeners: undefined,
     size: 106836,
     path: 'public/avatar/upload_d75420a381af12d19db01599fd2d0b73.jpeg',
     name: 'line.jpeg',
     type: 'image/jpeg',
     hash: null,
     lastModifiedDate: 2016-12-19T15:22:47.896Z,
     _writeStream: 
      WriteStream {
        _writableState: [Object],
        writable: false,
        domain: null,
        _events: {},
        _eventsCount: 0,
        _maxListeners: undefined,
        path: 'public/avatar/upload_d75420a381af12d19db01599fd2d0b73.jpeg',
        fd: null,
        flags: 'w',
        mode: 438,
        start: undefined,
        autoClose: true,
        pos: undefined,
        bytesWritten: 106836,
        closed: true } } }

以上數據用fs模塊讀取path屬性獲得是就是一段2進制的字符串;express

注:若是不配置express中間件,express是不能取到上傳的文件的,這一塊在路由回調函數的req上沒有作處理。

以上的示例基本就完成一些基本功能了;
疑惑就是網上一些jquery插件上傳圖片利用ajax,他們的原來是聲明呢 ?但願有人給解釋下

找到一篇類似的文章:

https://segmentfault.com/a/11...

補充:

var formData = new FormData();
 var fileObj = document.getElementById("file_upload").files[0];
 formData.append("fulAvatar", fileObj);

formData的兩種用法一種是直接將表單dom直接塞進去,還有一種就是經過append填進去,可是這裏要注意,填進去的是name和dom的files[0]屬性;

相關文章
相關標籤/搜索