express實現前后端通信上傳圖片,存儲數據庫(mysql)傻瓜教程(一)


  因昨天時間過於倉促,現對本文的一些內容進行補充,希望各位看官點評。

  在前端這個坑里摸爬滾打已經一年多了,終於下定決心寫下自己第一篇博客(雖然內容原創居少,算是個整合內容),開始使用express的原因是因為自己想測試接收下前端上傳圖片並返回,實現圖片上傳。后端各位大大們又都比較忙,沒辦法了,只能自己上了(哎,都是逼出來的)。

  此教程適合沒有接觸過node的web前端開發,快速構建自己的框架,基於express4.x。

  首先安裝express ,http://www.expressjs.com.cn/starter/installing.html,安裝過程中一直回車到底就ok了。

  安裝完成后,繼續安裝express的應用骨架,生成默認項目

$ npm install express-generator -g

  (-g表示全局安裝,下次可以直接使用,不用再次安裝)

  接着在myapp文件夾下直接運行express,項目目錄就直接生成了

  

   然后安裝所有依賴包:

$ npm install

  啟動這個應用(MacOS 或 Linux 平台):

$ DEBUG=myapp npm start

  Windows 平台使用如下命令:

> set DEBUG=myapp & npm start

  

   看到這個頁面時,大家已經完成了基礎的項目構建,繼續往上添加自己的代碼就可以了。(到這部后大家可以把public目錄下的文件夾修改為自己喜歡的格式,例如:js,css,只是一個路徑而已)

   接下來大家就可以把自己的頁面添加到項目里面了,不過express到目前我只發現可以加載jade模板和ejs。大家不用擔心還要從新學習jade,這里http://www.html2jade.org/,可以直接用工具把html轉化為jade模板,可以讓你手中已有的項目直接添加進去,

jade模板在express的加載方法:http://www.expressjs.com.cn/guide/using-template-engines.html。其實jade的寫法真的很簡單,大家看一下api基本就能上手了,學習地址點這里。(項目里已經集成了jade,不用重復安裝)

     項目里這兩行代碼加載了jade模板和路徑,

app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

 

   並且在routes/index.js加載了模板,res.render()方法是加載模板的代碼,可以自行查看,第一個參數代表文件名稱,第二個對象是傳遞模板定義的參數。   


 

    現在大家打開核心的app.js

          

   這幾行定義的是express的路由,大家可以簡單了解下路由的作用,http://www.expressjs.com.cn/guide/routing.html,這點非常重要,一定要理解,不是很難,應該能夠很快理解。

   比如現在你打開http://localhost:3000/users頁面,對應user.js里面的代碼一看就能理解。(打開這個頁面時發生了get請求)

   下面咱們先不急着上傳圖片,先測試下前端發送的post和get請求。

   以post請求為例,咱們把layout.jade修改成下面的樣子

doctype html
html
  head
    title= title
    link(rel='stylesheet', href='/css/style.css')
    script(type="text/javascript", src="/js/jquery.js")
    script(type="text/javascript", src="/js/index.js")
  body
    block content

  在public/js下新建個index.js,加載jquery(只是為了簡寫的ajax)有人可能會問為什么會沒有public路徑,因為Express 內置的 express.static 可以方便地托管靜態文件,例如圖片、CSS、JavaScript 文件等,詳細內容點這里,對應app.js的內容為 app.use(express.static(path.join(__dirname, 'public')));

只有這樣才能讀取到文件。

  下面開始修改js代碼,public/js/index.js內寫個最基礎的ajax請求就好了,這里發送請求的路徑為"/",就是往主頁發送請求(路由一定要理解,路由一定要理解,路由一定要理解!!)

$(document).ready(function() {
 $.post('/', {num: '12345678'}, function(data) {
   console.log(data)
});
})

   然后在routes/index.js里面修改

var express = require('express');
var router = express.Router();

/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index', { title: 'Express' });
});

router.post('/', function(req, res) {   
     res.send(req.body.num);
});

module.exports = router;

  在此監聽首頁的post請求,req.body.num表示發送過來的數據,大家可以直接打印下req,看看里面包含了什么內容,加深理解(修改完文件后記得重啟express)。

 

  

  這時候在控制台中就可以看到返回的數據了。


  現在大家已經可以使用node接收前端發送的請求了(是不是灰長開心!!),下面進行我們的重頭戲,上傳圖片。

  因為是測試接口,公司的項目要兼容低版本瀏覽器,所有plupload.js就上場了(不是我不想用h5的方法)。官網,下載后如圖,就夠用了。(記得在layout.jade里面加載)

  

  把index.js修改成下面的樣子,這是個標准的官網上傳事例,不理解的在官網看下api,很好理解(其實看變量名字也都能理解~)

$(document).ready(function() {
    var uploader = new plupload.Uploader({
        runtimes: 'html5,flash,silverlight,html4',
        browse_button: 'pickfiles', // you can pass an id...
        container: document.getElementById('container'), // ... or DOM Element itself
        url: '/',
        flash_swf_url: '../js/Moxie.swf',
        silverlight_xap_url: '../js/Moxie.xap',

        filters: {
            max_file_size: '10mb',
            mime_types: [{
                title: "Image files",
                extensions: "jpg,gif,png"
            }, {
                title: "Zip files",
                extensions: "zip"
            }]
        },

        init: {
            PostInit: function() {
                document.getElementById('filelist').innerHTML = '';

                document.getElementById('uploadfiles').onclick = function() {
                    uploader.start();
                    return false;
                };
            },

            FilesAdded: function(up, files) {
                plupload.each(files, function(file) {
                    document.getElementById('filelist').innerHTML += '<div id="' + file.id + '">' + file.name + ' (' + plupload.formatSize(file.size) + ') <b></b></div>';
                });
            },

            UploadProgress: function(up, file) {
                document.getElementById(file.id).getElementsByTagName('b')[0].innerHTML = '<span>' + file.percent + "%</span>";
            },

            Error: function(up, err) {
                document.getElementById('console').appendChild(document.createTextNode("\nError #" + err.code + ": " + err.message));
            },
            FileUploaded: function(up, file, info) {                 // Called when file has finished uploading                   
                 $("body").append($(info.response))                  
            },
            UploadComplete: function(up, file) {


            }
        }
    });

    uploader.init();

})

  index.jade修改成下面的樣子,主要是添加上傳點擊的元素,添加了兩個按鈕而已(不要嫌棄它確實是比較丑--)

extends layout

block content
  h1= title
  p Welcome to #{title}
  #filelist
  #container
   a#pickfiles select files
   a#uploadfiles upload files

  這里我們要用到的外部模塊是Felix Geisendörfer開發的node-formidable模塊。它對解析上傳的文件數據做了很好的抽象。 其實說白了,處理文件上傳“就是”處理POST數據 —— 但是,麻煩的是在具體的處理細節,所以,這里采用現成的方案更合適點。  

  安裝formidable模塊。

npm install formidable

  修改routes/index.js

var express = require('express');
var router = express.Router();
var fs = require('fs');
var formidable = require("formidable");


/* GET home page. */

router.get('/', function(req, res) {
    res.render('index', {
        title: '孟星魂'
    });

});

router.post('/', function(req, res) {
   
    var form = new formidable.IncomingForm();
    form.uploadDir = "./public/upload/temp/"; //改變臨時目錄
    form.parse(req, function(error, fields, files) {
        for (var key in files) {
            var file = files[key];
            var fName = (new Date()).getTime();
            switch (file.type) {
                case "image/jpeg":
                    fName = fName + ".jpg";
                    break;
                case "image/png":
                    fName = fName + ".png";
                    break;
                default:
                    fName = fName + ".png";
                    break;
            }
            console.log(file, file.size);
            var uploadDir = "./public/upload/" + fName;
            fs.rename(file.path, uploadDir, function(err) {
                if (err) {
                    res.write(err + "\n");
                    res.end();
                }
                //res.write("upload image:<br/>");
                res.write("<img src='/upload/" + fName + "' />");
                res.end();

            })

        }
    });
});

module.exports = router;

   此時需要在public下手動新建文件夾upload以及下面的temp文件夾。

  先把文件上傳到臨時文件夾,再通過fs重命名移動到指定的目錄即可。

  fs.rename即重命名,但是fs.rename不能誇磁盤移動文件,所以我們需要指定上傳的臨時目錄要和最終目錄在同一磁盤下。

  res.write就是往前端返回的數據,這里我直接返回一個img標簽,並添加上傳文件的路徑,前端只要把標簽append到頁面中就ok了。

  完成前端圖片上傳功能!!

  今天進行到這里,明天進行講解node連接數據庫的操作。

  歡迎任何形式的轉載,但請務必注明原文詳細鏈接。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM