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 - 如何引入js代码
Mar 09 Javascript
JS实多级联动下拉菜单类,简单实现省市区联动菜单!
May 03 Javascript
javascript分页代码实例分享(js分页)
Dec 13 Javascript
javascript操作excel生成报表全攻略
May 04 Javascript
在javascript中随机数 math random如何生成指定范围数值的随机数
Oct 21 Javascript
详解javascript中原始数据类型Null和Undefined
Dec 17 Javascript
Jquery和JS获取ul中li标签的实现方法
Jun 02 Javascript
浅谈JavaScript对象与继承
Jul 10 Javascript
浅谈js停止事件冒泡 阻止浏览器的默认行为(阻止超连接 #)
Feb 08 Javascript
vue 之 .sync 修饰符示例详解
Apr 21 Javascript
分享vue里swiper的一些坑
Aug 30 Javascript
jQuery实现的点击图片居中放大缩小功能示例
Jan 16 jQuery
基于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
ThinkPHP的L方法使用简介
2014/06/18 PHP
PHP5.5安装PHPRedis扩展及连接测试方法
2017/01/22 PHP
用javascript实现兼容IE7的类库 IE7_0_9.zip提供下载
2007/08/08 Javascript
JavaScript与Image加载事件(onload)、加载状态(complete)
2011/02/14 Javascript
关于jQuery中的end()使用方法
2011/07/10 Javascript
通过Javascript创建一个选择文件的对话框代码
2012/06/16 Javascript
js将long日期格式转换为标准日期格式实现思路
2013/04/07 Javascript
window.print打印指定div实例代码
2013/12/13 Javascript
jquery获取元素索引值index()示例
2014/02/13 Javascript
JS+HTML5手机开发之滚动和惯性缓动实现方法分析
2016/06/12 Javascript
解析Vue2.0双向绑定实现原理
2017/02/23 Javascript
全面分析JavaScript 继承
2019/05/30 Javascript
简单了解Javscript中兄弟ifream的方法调用
2019/06/17 Javascript
Nuxt.js nuxt-link与router-link的区别说明
2020/11/06 Javascript
[01:08:56]DOTA2-DPC中国联赛 正赛 Magma vs LBZS BO3 第一场 2月7日
2021/03/11 DOTA
用smtplib和email封装python发送邮件模块类分享
2014/02/17 Python
Python入门及进阶笔记 Python 内置函数小结
2014/08/09 Python
解决nohup重定向python输出到文件不成功的问题
2018/05/11 Python
详解python中的装饰器
2018/07/10 Python
python实现Virginia无密钥解密
2019/03/20 Python
深度辨析Python的eval()与exec()的方法
2019/03/26 Python
在python中利用numpy求解多项式以及多项式拟合的方法
2019/07/03 Python
tensorflow 大于某个值为1,小于为0的实例
2020/06/30 Python
PIP和conda 更换国内安装源的方法步骤
2020/09/21 Python
6种非常炫酷的CSS3按钮边框动画特效
2016/03/16 HTML / CSS
以特惠价提供在线奢侈品购物:FRMODA.com
2018/01/25 全球购物
美国领先的眼镜和太阳镜在线零售商:Glasses.com
2019/08/26 全球购物
旷课检讨书大全
2014/01/21 职场文书
减负增效提质方案
2014/05/23 职场文书
活动宣传策划方案
2014/05/23 职场文书
镇政府副镇长群众路线专题民主生活会对照检查材料
2014/09/19 职场文书
2015年会计工作总结范文
2015/05/26 职场文书
繁星春水读书笔记
2015/06/30 职场文书
800字作文之大雪
2019/12/04 职场文书
ORACLE数据库对long类型字段进行模糊匹配的解决思路
2021/04/07 Oracle
简单聊聊Golang中defer预计算参数
2022/03/25 Golang