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 相关文章推荐
js或css实现滚动广告的几种方案
Jan 28 Javascript
基于jquery的动态创建表格的插件
Apr 05 Javascript
jquery实现的带缩略图的焦点图片切换(自动播放/响应鼠标动作)
Jan 23 Javascript
js操作模态窗口及父子窗口间相互传值示例
Jun 09 Javascript
jQuery实现带滚动线条导航效果的方法
Jan 30 Javascript
Node.js的npm包管理器基础使用教程
May 26 Javascript
Android中Okhttp3实现上传多张图片同时传递参数
Feb 18 Javascript
Node.js调试技术总结分享
Mar 12 Javascript
关于vue中的ajax请求和axios包问题
Apr 19 Javascript
Vue创建头部组件示例代码详解
Oct 23 Javascript
webpack 从指定入口文件中提取公共文件的方法
Nov 13 Javascript
浅析JavaScript中的事件委托机制跟深浅拷贝
Jan 20 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中unlink()、mkdir()、rmdir()等方法的使用介绍
2012/12/21 PHP
php中替换字符串中的空格为逗号','的方法
2014/06/09 PHP
php实现微信公众平台账号自定义菜单类
2014/12/02 PHP
PHP中的命名空间详细介绍
2015/07/02 PHP
PHP中子类重载父类的方法【parent::方法名】
2016/05/06 PHP
PHP多种序列化/反序列化的方法详解
2017/06/23 PHP
Laravel框架路由管理简单示例
2019/05/07 PHP
JavaScript实现url地址自动检测并添加URL链接示例代码
2013/11/12 Javascript
jquery学习总结(超级详细)
2014/09/04 Javascript
NodeJS Web应用监听sock文件实例
2015/02/18 NodeJs
jQuery对象初始化的传参方式
2015/02/26 Javascript
深入理解JavaScript系列(41):设计模式之模板方法详解
2015/03/04 Javascript
异步JavaScript编程中的Promise使用方法
2015/07/28 Javascript
w3c编程挑战_初级脚本算法实战篇
2017/06/23 Javascript
vue+Java后端进行调试时解决跨域问题的方式
2017/10/19 Javascript
基于Vue插入视频的2种方法小结
2019/04/02 Javascript
Electron vue的使用教程图文详解
2019/07/05 Javascript
解决mui框架中switch开关通过js控制开或者关状态时小圆点不动的问题
2019/09/03 Javascript
vue从零实现一个消息通知组件的方法详解
2020/03/16 Javascript
vue 子组件和父组件传值的示例
2020/09/11 Javascript
ant-design表单处理和常用方法及自定义验证操作
2020/10/27 Javascript
python赋值操作方法分享
2013/03/23 Python
python中使用百度音乐搜索的api下载指定歌曲的lrc歌词
2014/07/18 Python
Python除法之传统除法、Floor除法及真除法实例详解
2019/05/23 Python
python中struct模块之字节型数据的处理方法
2019/08/27 Python
命令行运行Python脚本时传入参数的三种方式详解
2019/10/11 Python
Python编程快速上手——Excel表格创建乘法表案例分析
2020/02/28 Python
Python装饰器如何实现修复过程解析
2020/09/05 Python
基于CSS3实现的黑色个性导航菜单效果
2015/09/14 HTML / CSS
ivx平台开发之不用代码实现一个九宫格抽奖功能
2021/01/27 HTML / CSS
俄罗斯珠宝市场的领导者之一:Бронницкий ювелир
2019/10/02 全球购物
Hotels.com拉丁美洲:从豪华酒店到经济型酒店的预定优惠和折扣
2019/12/09 全球购物
C有"按引用传递"吗
2016/09/06 面试题
烟台的海导游词
2015/02/02 职场文书
手机销售员岗位职责
2015/04/11 职场文书
ConditionalOnProperty配置swagger不生效问题及解决
2022/06/14 Java/Android