node

node

Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。
javascript/jQuery

javascript/jQuery

一种直译式脚本语言,是一种动态类型、弱类型、基于原型的语言,内置支持类型。
MongoDB

MongoDB

MongoDB 是一个基于分布式文件存储的数据库
openstack

openstack

OpenStack是一个由NASA(美国国家航空航天局)和Rackspace合作研发并发起的,以Apache许可证授权的自由软件和开放源代码项目。
VUE

VUE

一套构建用户界面的渐进式框架。与其他重量级框架不同的是,Vue 采用自底向上增量开发的设计。
bootstrap

bootstrap

Bootstrap is the most popular HTML, CSS, and JS framework for developing responsive, mobile first projects on the web.
HTML

HTML

超文本标记语言,标准通用标记语言下的一个应用。
CSS/SASS/SCSS/Less

CSS/SASS/SCSS/Less

层叠样式表(英文全称:Cascading Style Sheets)是一种用来表现HTML(标准通用标记语言的一个应用)或XML(标准通用标记语言的一个子集)等文件样式的计算机语言。
PHP

PHP

PHP(外文名:PHP: Hypertext Preprocessor,中文名:“超文本预处理器”)是一种通用开源脚本语言。语法吸收了C语言、Java和Perl的特点,利于学习,使用广泛,主要适用于Web开发领域。PHP 独特的语法混合了C、Java、Perl以及PHP自创的语法。它可以比CGI或者Perl更快速地执行动态网页。用PHP做出的动态页面与其他的编程语言相比,PHP是将程序嵌入到HTML(标准通用标记语言下的一个应用)文档中去执行,执行效率比完全生成HTML标记的CGI要高许多;PHP还可以执
每天进步一点点

每天进步一点点

乌法把门的各累笑寂静
求职招聘

求职招聘

猎头招聘专用栏目
Python

Python

一种解释型、面向对象、动态数据类型的高级程序设计语言。

解决产品上线后需要客户清理浏览器缓存才行的简单方案

yinzi 发表了文章 • 2 个评论 • 1876 次浏览 • 2017-07-12 16:47 • 来自相关话题

产品上线后总是需要客户自己清理浏览器缓存才能读取最新的js和css,最简单的方案,就是在js引用路径后面加一个变化的参数,如
<script type="text/javascript" src="assets/js/app.js?v=201707121646"></script>
亲测有效
? 查看全部
产品上线后总是需要客户自己清理浏览器缓存才能读取最新的js和css,最简单的方案,就是在js引用路径后面加一个变化的参数,如
<script type="text/javascript" src="assets/js/app.js?v=201707121646"></script>
亲测有效
?

求大神指点

lopo1983 回复了问题 • 2 人关注 • 1 个回复 • 1649 次浏览 • 2017-07-06 17:04 • 来自相关话题

移动端页面开发总结(三)

boloog 发表了文章 • 0 个评论 • 1682 次浏览 • 2017-05-09 15:37 • 来自相关话题

CSS reset
@charset "utf-8";
html{
-webkit-text-size-adjust:none;
-webkit-user-select:none;
-webkit-touch-callout: none;
font-family: Microsoft YaHei,'宋体' , Tahoma, Helvetica, Arial, "\5b8b\4f53", sans-serif;
font-size:24px;
}
body,h1,h2,h3,h4,h5,h6,p,dl,dd,ul,ol,pre,form,input,textarea,th,td,select{
margin:0;
padding:0;
font-weight: normal;
}
a,button,input,textarea,select{
background: none;
-webkit-tap-highlight-color:rgba(255,0,0,0);
outline:none;
-webkit-appearance:none;
}
ol,ul{
list-style:none;
}
a{
text-decoration:none;
}
img{
border:none;
text-decoration: none;
}
table{
border-collapse:collapse;
border-spacing: 0;
}
textarea{
resize:none;
overflow:auto;
}
清除浮动
.clearfix{
zoom:1;
}
.clearfix:after {
clear:both;
display:block;
height:0;
content:"";
visibility:hidden;
}
禁止换行 超出文本用省略号代替
.no-wrap-ellipsis{
white-space:nowrap;
overflow:hidden;
text-overflow:ellipsis;
}
使文本文字两端对齐
.text-justify{
text-align:justify;
text-justify:inter-ideograph;
}
CSS判断横屏竖屏
@media screen and (orientation: portrait) {
/*竖屏 css*/
}
@media screen and (orientation: landscape) {
/*横屏 css*/
}
?取消长按复制 获取长按复制
.text-nocopy {
-webkit-touch-callout:none;
-webkit-user-select:none;
-khtml-user-select:none;
-moz-user-select:none;
-ms-user-select:none;
user-select:none;
}
.text-copy{
-webkit-touch-callout:text;
-webkit-user-select:text;
-moz-user-select:text;
-ms-user-select:text;
user-select:text;
}
?
?
?
? 查看全部
CSS reset
@charset "utf-8";
html{
-webkit-text-size-adjust:none;
-webkit-user-select:none;
-webkit-touch-callout: none;
font-family: Microsoft YaHei,'宋体' , Tahoma, Helvetica, Arial, "\5b8b\4f53", sans-serif;
font-size:24px;
}
body,h1,h2,h3,h4,h5,h6,p,dl,dd,ul,ol,pre,form,input,textarea,th,td,select{
margin:0;
padding:0;
font-weight: normal;
}
a,button,input,textarea,select{
background: none;
-webkit-tap-highlight-color:rgba(255,0,0,0);
outline:none;
-webkit-appearance:none;
}
ol,ul{
list-style:none;
}
a{
text-decoration:none;
}
img{
border:none;
text-decoration: none;
}
table{
border-collapse:collapse;
border-spacing: 0;
}
textarea{
resize:none;
overflow:auto;
}

清除浮动
.clearfix{ 
zoom:1;
}
.clearfix:after {
clear:both;
display:block;
height:0;
content:"";
visibility:hidden;
}

禁止换行 超出文本用省略号代替
.no-wrap-ellipsis{ 
white-space:nowrap;
overflow:hidden;
text-overflow:ellipsis;
}

使文本文字两端对齐
.text-justify{ 
text-align:justify;
text-justify:inter-ideograph;
}

CSS判断横屏竖屏
@media screen and (orientation: portrait) {
/*竖屏 css*/
}
@media screen and (orientation: landscape) {
/*横屏 css*/
}

?取消长按复制 获取长按复制
.text-nocopy {
-webkit-touch-callout:none;
-webkit-user-select:none;
-khtml-user-select:none;
-moz-user-select:none;
-ms-user-select:none;
user-select:none;
}
.text-copy{
-webkit-touch-callout:text;
-webkit-user-select:text;
-moz-user-select:text;
-ms-user-select:text;
user-select:text;
}

?
?
?
?

移动端页面开发总结(二)

boloog 发表了文章 • 0 个评论 • 1751 次浏览 • 2017-05-09 14:55 • 来自相关话题

CSS的样式技巧?
?
1、禁止ios和android用户选中文字
html{-webkit-user-select:none;}
2、禁止ios长按时触发系统的菜单,禁止ios&android长按时下载图片
html{-webkit-touch-callout: none;}
3、webkit去除表单元素的默认样式
input{-webkit-appearance:none;}
4、修改webkit表单输入框placeholder的样式
input::-webkit-input-placeholder{color:#123456;}
input:focus::-webkit-input-placeholder{color:#654321;}
5、去除android设备下面的 a/button/input标签被点击时产生的边框 & 去除ios a标签被点击时产生的半透明灰色背景
a,button,input{-webkit-tap-highlight-color:rgba(255,0,0,0);}
6、ios使用-webkit-text-size-adjust禁止调整字体大小
body{-webkit-text-size-adjust: 100%!important;}
7、android 上去掉语音输入按钮
input::-webkit-input-speech-button {display: none;}
8、定义字体
font-family:'\5FAE\8F6F\96C5\9ED1',tahoma,'\5b8b\4f53',"Helvetica Neue",Helvetica,Arial,sans-serif;
? 查看全部
CSS的样式技巧?
?
1、禁止ios和android用户选中文字
html{-webkit-user-select:none;}

2、禁止ios长按时触发系统的菜单,禁止ios&android长按时下载图片
html{-webkit-touch-callout: none;}

3、webkit去除表单元素的默认样式
input{-webkit-appearance:none;}

4、修改webkit表单输入框placeholder的样式
input::-webkit-input-placeholder{color:#123456;}
input:focus::-webkit-input-placeholder{color:#654321;}

5、去除android设备下面的 a/button/input标签被点击时产生的边框 & 去除ios a标签被点击时产生的半透明灰色背景
a,button,input{-webkit-tap-highlight-color:rgba(255,0,0,0);}

6、ios使用-webkit-text-size-adjust禁止调整字体大小
body{-webkit-text-size-adjust: 100%!important;}

7、android 上去掉语音输入按钮
input::-webkit-input-speech-button {display: none;}

8、定义字体
font-family:'\5FAE\8F6F\96C5\9ED1',tahoma,'\5b8b\4f53',"Helvetica Neue",Helvetica,Arial,sans-serif;

?

移动端页面开发总结(一)

boloog 发表了文章 • 0 个评论 • 1769 次浏览 • 2017-05-09 14:39 • 来自相关话题

meta标签的相关知识
?1、移动端页面设置视口宽度等于设备宽度,并禁止缩放。
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" />
?2、移动端页面设置视口宽度等于定宽(如750px),并禁止缩放,常用于微信浏览器页面。
<meta name="viewport" content="width=750, user-scalable=no, target-densitydpi=device-dpi">
3、禁止将页面中的数字识别为电话号码
<meta name="format-detection" content="telephone=no" />
4、忽略Android平台中对邮箱地址的识别
<meta name="format-detection" content="email=no" />
5、当网站添加到主屏幕快速启动方式,可隐藏地址栏,仅针对ios的safari
<meta name="apple-mobile-web-app-capable" content="yes" />
6、将网站添加到主屏幕快速启动方式,仅针对ios的safari顶端状态条的样式
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
html5 viewport模板
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no" name="viewport">
<meta content="yes" name="apple-mobile-web-app-capable">
<meta content="black" name="apple-mobile-web-app-status-bar-style">
<meta content="telephone=no" name="format-detection">
<meta content="email=no" name="format-detection">
<title>Document</title>
</head>
<body>
content...
</body>
</html>
?
?
?
?
? 查看全部
meta标签的相关知识
?1、移动端页面设置视口宽度等于设备宽度,并禁止缩放。
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" />

?2、移动端页面设置视口宽度等于定宽(如750px),并禁止缩放,常用于微信浏览器页面。
<meta name="viewport" content="width=750, user-scalable=no, target-densitydpi=device-dpi">

3、禁止将页面中的数字识别为电话号码
<meta name="format-detection" content="telephone=no" />

4、忽略Android平台中对邮箱地址的识别
<meta name="format-detection" content="email=no" />

5、当网站添加到主屏幕快速启动方式,可隐藏地址栏,仅针对ios的safari
<meta name="apple-mobile-web-app-capable" content="yes" />

6、将网站添加到主屏幕快速启动方式,仅针对ios的safari顶端状态条的样式
<meta name="apple-mobile-web-app-status-bar-style" content="black" />

html5 viewport模板
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no" name="viewport">
<meta content="yes" name="apple-mobile-web-app-capable">
<meta content="black" name="apple-mobile-web-app-status-bar-style">
<meta content="telephone=no" name="format-detection">
<meta content="email=no" name="format-detection">
<title>Document</title>
</head>
<body>
content...
</body>
</html>

?
?
?
?
?

网页媒体播放器都有哪些?

lopo1983 回复了问题 • 2 人关注 • 1 个回复 • 2320 次浏览 • 2017-04-21 16:08 • 来自相关话题

HTML5 中的新属性 async和defer区别

boloog 发表了文章 • 0 个评论 • 1659 次浏览 • 2017-04-20 18:30 • 来自相关话题

浏览器支持情况:
Internet Explorer 10、Firefox、Opera、Chrome 和 Safari 支持?async?defer?属性。
?
简述:<script async src="common.js"></script>有?async?脚本相对于页面的其余部分异步地执行(当页面继续进行解析时,脚本将被执行)
?<script defer src="index.js"></script>
?有?defer?脚本将在页面完成解析时执行,但 index.js 的执行要在所有元素解析完成之后,DOMContentLoaded 事件触发之前完成。<script src="index.js"></script>
?没有?defer?或?async,浏览器会立即加载并执行指定的脚本,“立即”指的是在渲染该?script标签之下的文档元素之前,也就是说不等待后续载入的文档元素,读到就加载并执行。
?

实例代码:<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>HTML5 中的新属性 async和defer区别</title>
</head>
<body>
<script async src="./common.js"></script>
<script defer src="./index.js"></script>
<script>
console.log(1111);
</script>
</body>
</html>
?运行结果:1111
index.js
common.js
?
?
?
? 查看全部
浏览器支持情况:
Internet Explorer 10、Firefox、Opera、Chrome 和 Safari 支持?async?defer?属性。
?
简述:
<script async src="common.js"></script>
有?async?脚本相对于页面的其余部分异步地执行(当页面继续进行解析时,脚本将被执行)
?
<script defer src="index.js"></script>

?有?defer?脚本将在页面完成解析时执行,但 index.js 的执行要在所有元素解析完成之后,DOMContentLoaded 事件触发之前完成。
<script src="index.js"></script>

?没有?defer?或?async,浏览器会立即加载并执行指定的脚本,“立即”指的是在渲染该?script标签之下的文档元素之前,也就是说不等待后续载入的文档元素,读到就加载并执行。
?

实例代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>HTML5 中的新属性 async和defer区别</title>
</head>
<body>
<script async src="./common.js"></script>
<script defer src="./index.js"></script>
<script>
console.log(1111);
</script>
</body>
</html>

?运行结果:
1111
index.js
common.js

?
?
?
?

理解HTML

回复

boloog 发起了问题 • 2 人关注 • 0 个回复 • 2887 次浏览 • 2017-04-17 18:50 • 来自相关话题

HTML5 实现手机拍照上传

lopo1983 发表了文章 • 0 个评论 • 2412 次浏览 • 2016-08-30 11:11 • 来自相关话题

页面样式:上传图片有原生的方法<input type="file" accept="image/*">,如果只想要拍照上传,不希望用户选择图片上传,可以通过添加capture属性,该属性值有camcorder/microphone/camera...,此处选择camera。
PS:该属性存在浏览器兼容性问题,不是所有的浏览器都支持。
<input type="file" accept="image/*" capture="camera" >因为原生file样式不满足要求,需要进行相应的处理,此时使用定位,在input上面放置我们想要的页面效果。然后当点击上面的元素,就可以触发我们的input进行图片上传。此时的问题是:当点击input上面的元素,需要事件穿透,即相当于点击input。则借助于css3新属性pointer-events。
button{
cursor:pointer;
pointer-events:none;
}----此时图片上传的样式已经处理好了
----代码片段:
<style >
*{
padding: 0;
margin: 0;
}
.wrapper{
width: 320px;
height: 50px;
margin: 20px auto;
position: relative;
border: 1px solid #f0f0f0;
}
input{
width: 100px;
height: 30px;
}
button{
position: absolute;
cursor: pointer;
pointer-events: none;
width: 100px;
height: 30px;
left: 0;
top: 0;
}
a{
pointer-events: none;
}
.img{
border: 1px solid #ccc;
padding: 10px;
}
</style >

<div class = "wrapper">
<input type = "file" accept= "image/*" capture= "camera" id= "img" />
<button >上传照片 </button >
</div >
?
图片压缩处理:
因为要做的是手机拍照上传,现在的手机拍照片都很大,比如小米4S,大小在3M以上,如果原图上传,太消耗用户流量,于是要解决图片压缩的问题。
通过change事件,监听图片上传,通过readerAsDataURL获取上传的图片。
document.getElementById( 'img').addEventListener( 'change', function () {
var reader = new FileReader();
reader.onload = function (e) {
//调用图片压缩方法:compress();
};
reader.readAsDataURL(this.files[0]);
console.log(this.files[0]);
var fileSize = Math.round( this.files[0].size/1024/1024) ; //以M为单位
//this.files[0] 该信息包含:图片的大小,以byte计算 获取size的方法如下:this.files[0].size;
}, false);对上传的图片进行压缩,需要借助于canvas API,调用其中canvas.toDataURL(type,?encoderOptions);?将图片按照一定的压缩比进行压缩,得到base64编码。重点来了:压缩策略:先设置图片的最大宽度 or 最大高度,一般设置其中一个就可以了,因为所有的手机宽高比差别不是很大。然后设置图片的最大size,allowMaxSize,根据图片的实际大小和最大允许大小,设置相应的压缩比率。
//最终实现思路:
1、设置压缩后的最大宽度 or 高度;
2、设置压缩比例,根据图片的不同size大小,设置不同的压缩比。

function compress(res,fileSize) { //res代表上传的图片,fileSize大小图片的大小
var img = new Image(),
maxW = 640; //设置最大宽度

img.onload = function () {
var cvs = document.createElement( 'canvas'),
ctx = cvs.getContext( '2d');

if(img.width > maxW) {
img.height *= maxW / img.width;
img.width = maxW;
}

cvs.width = img.width;
cvs.height = img.height;

ctx.clearRect(0, 0, cvs.width, cvs.height);
ctx.drawImage(img, 0, 0, img.width, img.height);

var compressRate = getCompressRate(1,fileSize);

var dataUrl = cvs.toDataURL( 'image/jpeg', compressRate);

document.body.appendChild(cvs);
console.log(dataUrl);
}

img.src = res;
}

function getCompressRate(allowMaxSize,fileSize){ //计算压缩比率,size单位为MB
var compressRate = 1;

if(fileSize/allowMaxSize > 4){
compressRate = 0.5;
} else if(fileSize/allowMaxSize >3){
compressRate = 0.6;
} else if(fileSize/allowMaxSize >2){
compressRate = 0.7;
} else if(fileSize > allowMaxSize){
compressRate = 0.8;
} else{
compressRate = 0.9;
}

return compressRate;
}
?
图片上传给服务器:图片已经压缩完成了,但是压缩后的图片不是File,而是一个base64编码,于是乎两个选择:1、以String的形式将base64编码上传给服务器,服务器转存base64为img图片;2、前端将base64转为File图片类型,上传给服务器。
方法一:压缩之后直接上传base64给后台,实现简单。
方法二:前端自己转存base64位File图片,这个对于前端 压力比较大。

原因:html5 canvas属于客户端API,没有权限去保存图片到硬盘,只有canvas.toDataURL()这一接口可导出画布的base64编码,以提供给服务器进行处理保存。所以如果要将base64编码转成图片需要借助于nodeJs。因为nodeJS有相关文件处理的API。
//使用nodeJS将base64转化成图片
var express = require('express');
var fs = require("fs");
var app = module.exports = express();

function dataToImage(dataUrl){
var base64Data = dataUrl.replace(/^data:image\/\w+;base64,/,'');
var dataBuffer = new Buffer(base64Data,'base64');

fs.writeFile('out.jpg',dataBuffer,function(err){
if(err){
console.log(err);
}else{
console.log('Success...');
}
});
}

dataToImage('data:image/jpeg;base64,/9...'); //图片完整base64过长,所以省略...

if(!module.parent){
app.listen(8000);
console.log('Express started on port 8000');
}Summary:如果使用nodeJS,需要单独部署nodeJS代码到服务器,整个逻辑会比较麻烦。综合比较两种方法,推荐使用第一种方法,直接传base64给服务器,后台处理相应的转化! 查看全部
页面样式:上传图片有原生的方法<input type="file" accept="image/*">,如果只想要拍照上传,不希望用户选择图片上传,可以通过添加capture属性,该属性值有camcorder/microphone/camera...,此处选择camera。
PS:该属性存在浏览器兼容性问题,不是所有的浏览器都支持。
<input type="file" accept="image/*" capture="camera" >
因为原生file样式不满足要求,需要进行相应的处理,此时使用定位,在input上面放置我们想要的页面效果。然后当点击上面的元素,就可以触发我们的input进行图片上传。此时的问题是:当点击input上面的元素,需要事件穿透,即相当于点击input。则借助于css3新属性pointer-events。
button{
cursor:pointer;
pointer-events:none;
}
----此时图片上传的样式已经处理好了
----代码片段:
<style >
*{
padding: 0;
margin: 0;
}
.wrapper{
width: 320px;
height: 50px;
margin: 20px auto;
position: relative;
border: 1px solid #f0f0f0;
}
input{
width: 100px;
height: 30px;
}
button{
position: absolute;
cursor: pointer;
pointer-events: none;
width: 100px;
height: 30px;
left: 0;
top: 0;
}
a{
pointer-events: none;
}
.img{
border: 1px solid #ccc;
padding: 10px;
}
</style >

<div class = "wrapper">
<input type = "file" accept= "image/*" capture= "camera" id= "img" />
<button >上传照片 </button >
</div >

?
图片压缩处理:
因为要做的是手机拍照上传,现在的手机拍照片都很大,比如小米4S,大小在3M以上,如果原图上传,太消耗用户流量,于是要解决图片压缩的问题。
通过change事件,监听图片上传,通过readerAsDataURL获取上传的图片。
document.getElementById( 'img').addEventListener( 'change', function () {
var reader = new FileReader();
reader.onload = function (e) {
//调用图片压缩方法:compress();
};
reader.readAsDataURL(this.files[0]);
console.log(this.files[0]);
var fileSize = Math.round( this.files[0].size/1024/1024) ; //以M为单位
//this.files[0] 该信息包含:图片的大小,以byte计算 获取size的方法如下:this.files[0].size;
}, false);
对上传的图片进行压缩,需要借助于canvas API,调用其中canvas.toDataURL(type,?encoderOptions);?将图片按照一定的压缩比进行压缩,得到base64编码。重点来了:压缩策略:先设置图片的最大宽度 or 最大高度,一般设置其中一个就可以了,因为所有的手机宽高比差别不是很大。然后设置图片的最大size,allowMaxSize,根据图片的实际大小和最大允许大小,设置相应的压缩比率。
//最终实现思路:
1、设置压缩后的最大宽度 or 高度;
2、设置压缩比例,根据图片的不同size大小,设置不同的压缩比。

function compress(res,fileSize) { //res代表上传的图片,fileSize大小图片的大小
var img = new Image(),
maxW = 640; //设置最大宽度

img.onload = function () {
var cvs = document.createElement( 'canvas'),
ctx = cvs.getContext( '2d');

if(img.width > maxW) {
img.height *= maxW / img.width;
img.width = maxW;
}

cvs.width = img.width;
cvs.height = img.height;

ctx.clearRect(0, 0, cvs.width, cvs.height);
ctx.drawImage(img, 0, 0, img.width, img.height);

var compressRate = getCompressRate(1,fileSize);

var dataUrl = cvs.toDataURL( 'image/jpeg', compressRate);

document.body.appendChild(cvs);
console.log(dataUrl);
}

img.src = res;
}

function getCompressRate(allowMaxSize,fileSize){ //计算压缩比率,size单位为MB
var compressRate = 1;

if(fileSize/allowMaxSize > 4){
compressRate = 0.5;
} else if(fileSize/allowMaxSize >3){
compressRate = 0.6;
} else if(fileSize/allowMaxSize >2){
compressRate = 0.7;
} else if(fileSize > allowMaxSize){
compressRate = 0.8;
} else{
compressRate = 0.9;
}

return compressRate;
}

?
图片上传给服务器:图片已经压缩完成了,但是压缩后的图片不是File,而是一个base64编码,于是乎两个选择:1、以String的形式将base64编码上传给服务器,服务器转存base64为img图片;2、前端将base64转为File图片类型,上传给服务器。
方法一:压缩之后直接上传base64给后台,实现简单。
方法二:前端自己转存base64位File图片,这个对于前端 压力比较大。

原因:html5 canvas属于客户端API,没有权限去保存图片到硬盘,只有canvas.toDataURL()这一接口可导出画布的base64编码,以提供给服务器进行处理保存。所以如果要将base64编码转成图片需要借助于nodeJs。因为nodeJS有相关文件处理的API。
//使用nodeJS将base64转化成图片
var express = require('express');
var fs = require("fs");
var app = module.exports = express();

function dataToImage(dataUrl){
var base64Data = dataUrl.replace(/^data:image\/\w+;base64,/,'');
var dataBuffer = new Buffer(base64Data,'base64');

fs.writeFile('out.jpg',dataBuffer,function(err){
if(err){
console.log(err);
}else{
console.log('Success...');
}
});
}

dataToImage('data:image/jpeg;base64,/9...'); //图片完整base64过长,所以省略...

if(!module.parent){
app.listen(8000);
console.log('Express started on port 8000');
}
Summary:如果使用nodeJS,需要单独部署nodeJS代码到服务器,整个逻辑会比较麻烦。综合比较两种方法,推荐使用第一种方法,直接传base64给服务器,后台处理相应的转化!