Express实现前端后端通信上传图片之存储数据库(mysql)傻瓜式教程(一)


Posted in Javascript onDecember 10, 2015

在前端这个坑里摸爬滚打已经一年多了,终于下定决心写下自己第一篇博客(虽然内容原创居少,算是个整合内容),开始使用express的原因是因为自己想测试接收下前端上传图片并返回,实现图片上传。后端各位大大们又都比较忙,没办法了,只能自己上了(哎,都是逼出来的)。

此教程适合没有接触过node的web前端开发,快速构建自己的框架,基于express4.x。

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

安装完成后,继续安装express的应用骨架,生成默认项目

$ npm install express-generator -g

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

接着在myapp文件夹下直接运行express,项目目录就直接生成了 

Express实现前端后端通信上传图片之存储数据库(mysql)傻瓜式教程(一)

    然后安装所有依赖包:

$ npm install

启动这个应用(MacOS 或 Linux 平台):

$ DEBUG=myapp npm start

Windows 平台使用如下命令:

> set DEBUG=myapp & npm start

Express实现前端后端通信上传图片之存储数据库(mysql)傻瓜式教程(一)

 看到这个页面时,大家已经完成了基础的项目构建,继续往上添加自己的代码就可以了。(到这部后大家可以把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,不用重复安装)

 

 现在大家打开核心的app.js

Express实现前端后端通信上传图片之存储数据库(mysql)傻瓜式教程(一)

这几行定义的是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)。

Express实现前端后端通信上传图片之存储数据库(mysql)傻瓜式教程(一)

这时候在控制台中就可以看到返回的数据了。

现在大家已经可以使用node接收前端发送的请求了(是不是灰长开心!!),下面进行我们的重头戏,上传图片。

因为是测试接口,公司的项目要兼容低版本浏览器,所有plupload.js就上场了(不是我不想用h5的方法)。官网,下载后如图,就够用了。(记得在layout.jade里面加载)

Express实现前端后端通信上传图片之存储数据库(mysql)傻瓜式教程(一)

把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连接数据库的操作。

Javascript 相关文章推荐
一些Javascript的IE和Firefox(火狐)兼容性的问题总结及常用例子
May 21 Javascript
jQuery EasyUI NumberBox(数字框)的用法
Jul 08 Javascript
基于JQuery的一个简单的鼠标跟随提示效果
Sep 23 Javascript
Dom 是什么的详细说明
Oct 25 Javascript
12种JavaScript常用的MVC框架比较分析
Nov 16 Javascript
Javascript 普通函数和构造函数的区别
Nov 05 Javascript
JAVA中截取字符串substring用法详解
Apr 14 Javascript
vue计算属性computed、事件、监听器watch的使用讲解
Jan 21 Javascript
JavaScript学习教程之cookie与webstorage
Jun 23 Javascript
js实现随机数小游戏
Jun 28 Javascript
Electron 调用命令行(cmd)
Sep 23 Javascript
Layui带搜索的下拉框的使用以及动态数据绑定方法
Sep 28 Javascript
基于jQuery实现复选框是否选中进行答题提示
Dec 10 #Javascript
日常收集整理的JavaScript常用函数方法
Dec 10 #Javascript
详解AngularJS中module模块的导入导出
Dec 10 #Javascript
SpringMVC restful 注解之@RequestBody进行json与object转换
Dec 10 #Javascript
Spring mvc 接收json对象
Dec 10 #Javascript
SpringMVC返回json数据的三种方式
Dec 10 #Javascript
js操作数组函数实例小结
Dec 10 #Javascript
You might like
PHP memcache扩展的三种安装方法
2009/04/26 PHP
基于PHP中的常用函数回顾
2013/07/11 PHP
mantis安装、配置和使用中的问题小结
2014/07/14 PHP
PHP的Yii框架中Model模型的学习教程
2016/03/29 PHP
php操纵mysqli数据库的实现方法
2016/09/18 PHP
php redis实现对200w用户的即时推送
2017/03/04 PHP
JS操作XML中DTD介绍及使用方法分析
2019/07/04 PHP
解析jquery获取父窗口的元素
2013/06/26 Javascript
9行javascript代码获取QQ群成员具体实现
2013/10/16 Javascript
firefox下jquery ajax返回object XMLDocument处理方法
2014/01/26 Javascript
jquery JSON的解析方式示例介绍
2014/07/27 Javascript
JavaScript验证18位身份证号码最后一位正确性的实现代码
2014/08/07 Javascript
基于jQuery的Web上传插件Uploadify使用示例
2016/05/19 Javascript
浅谈Vue的基本应用
2016/12/27 Javascript
JS中mouseup事件丢失的原因与解决办法
2017/06/14 Javascript
微信小程序-API接口安全详解
2019/07/16 Javascript
微信小程序自定义头部导航栏(组件化)
2019/11/15 Javascript
Vue CLI4 Vue.config.js标准配置(最全注释)
2020/06/05 Javascript
[55:39]DOTA2-DPC中国联赛 正赛 VG vs LBZS BO3 第二场 1月19日
2021/03/11 DOTA
Python中input和raw_input的一点区别
2014/10/21 Python
Python实现字典的key和values的交换
2015/08/04 Python
python生成验证码图片代码分享
2016/01/28 Python
python实现飞机大战微信小游戏
2020/03/21 Python
python 初始化一个定长的数组实例
2019/12/02 Python
python语音识别指南终极版(有这一篇足矣)
2020/09/09 Python
HTML5 新旧语法标记对我们有什么好处
2012/12/13 HTML / CSS
基于MUI框架使用HTML5实现的二维码扫描功能
2018/03/01 HTML / CSS
Proenza Schouler官方网站:纽约女装和配饰品牌
2019/01/03 全球购物
我能否用void** 指针作为参数, 使函数按引用接受一般指针
2013/02/16 面试题
外贸公司实习自我鉴定
2013/09/24 职场文书
英文推荐信格式范文
2014/05/09 职场文书
2014向国旗敬礼网上签名活动总结
2014/09/27 职场文书
生产现场禁烟通知
2015/04/23 职场文书
灵魂歌王观后感
2015/06/17 职场文书
2016年社区党支部公开承诺书
2016/03/25 职场文书
vue配置型表格基于el-table拓展之table-plus组件
2022/04/12 Vue.js