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 相关文章推荐
prototype 中文参数乱码解决方案
Nov 09 Javascript
JQuery一种取同级值的方式(比如你在GridView中)
Mar 15 Javascript
Javascript继承(上)——对象构建介绍
Nov 08 Javascript
node.js中的url.parse方法使用说明
Dec 10 Javascript
基于jQuery实现Div窗口震动特效代码-代码简单
Aug 28 Javascript
浅析JavaScript的几种Math函数,random(),ceil(),round(),floor()
Dec 22 Javascript
javascript 封装Date日期类实例详解
May 28 Javascript
ES6中let 和 const 的新特性
Sep 03 Javascript
Vue.js 实现数据展示全部和收起功能
Sep 05 Javascript
详解webpack编译速度提升之DllPlugin
Feb 05 Javascript
js中let能否完全替代IIFE
Jun 15 Javascript
vue实现input输入模糊查询的三种方式
Aug 14 Vue.js
基于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
微信公众平台开发之天气预报功能
2015/08/31 PHP
如何使用GDB调试PHP程序
2015/12/08 PHP
PHP简单日历实现方法
2016/07/20 PHP
[原创]php正则删除img标签的方法示例
2017/05/27 PHP
php实现算术验证码功能
2018/12/05 PHP
PHP-FPM和Nginx的通信机制详解
2019/02/01 PHP
一些易混淆且不常用的属性,希望有用
2007/01/29 Javascript
js面向对象 多种创建对象方法小结
2012/05/21 Javascript
可简单避免的三个JS发布错误的详细介绍
2013/08/02 Javascript
js 固定悬浮效果实现思路代码
2013/08/02 Javascript
JavaScript中的迭代器和生成器详解
2014/10/29 Javascript
node.js中的fs.fchown方法使用说明
2014/12/16 Javascript
jQuery解决input超多的表单提交
2015/08/10 Javascript
当jquery ajax遇上401请求的解决方法
2016/05/19 Javascript
使用jquery给新生的th绑定hover事件的实例
2017/02/10 Javascript
浅谈Vue数据响应
2018/11/05 Javascript
NestJs 静态目录配置详解
2019/03/12 Javascript
jQuery zTree树插件的使用教程
2019/08/16 jQuery
微信小程序仿今日头条导航栏滚动解析
2019/08/20 Javascript
python中利用zfill方法自动给数字前面补0
2018/04/10 Python
Python实现的多进程拷贝文件并显示百分比功能示例
2019/04/09 Python
Pythony运维入门之Socket网络编程详解
2019/04/15 Python
在pycharm中关掉ipython console/PyDev操作
2020/06/09 Python
解决TensorFlow调用Keras库函数存在的问题
2020/07/06 Python
详解html5 postMessage解决跨域通信的问题
2018/08/17 HTML / CSS
微软中国官方商城:Microsoft Store中国
2018/10/12 全球购物
Madda Fella官网:美国冒险家服装品牌
2020/01/16 全球购物
Wallis官网:英国女装零售商
2020/01/21 全球购物
一些关于MySql加速和优化的面试题
2014/01/30 面试题
秋季红领巾广播稿
2014/01/27 职场文书
村居抓节水倡议书
2014/05/19 职场文书
助学感谢信范文
2015/01/21 职场文书
2016年高校自主招生自荐信范文
2015/03/24 职场文书
2019年暑期法院实习报告
2019/12/18 职场文书
Redis读写分离搭建的完整步骤
2021/09/14 Redis
Win11电脑显示本地时间与服务器时间不一致怎么解决?
2022/04/05 数码科技