html5调用手机相机并压缩、上传
近日刚做的一个功能,要在app里使用内嵌页面进行图像的上传。 从功能上看,原生的实现应该是最好的。毕竟页面上所有的东西都隔着一个浏览器,所有的实现都要依赖浏览器提供的接口,不同的浏览器对接口的实现又有差异……到最后又会陷入兼容性的大坑! 吐槽归吐槽,但是折腾的劲头不能丢! 使用input file[camera]属性调用相机 简直So easy!
1 2 |
<input type="file" accept="image/*;" capture="camera" > |
只需要这么一条简单的代码,在手机浏览器点击就可以打开相机了。 capture是什么?其实就是对打开方式的设置。
1 2 3 4 5 |
<!-- capture=camcorder,调用手机摄像功能 --> <input type="file" accept="video/*" capture="camcorder" > <!-- capture=microphone,调用手机录音功能 --> <input type="file" accept="audio/*" capture="microphone" > |
魅族MX5测试结果: 谷歌浏览器可以打开相机和摄像功能,其他方式均为相机、图库、文件管理器等混合选择项。 自带浏览器打开均为文件管理器。 由此说明此属性兼容性还是个问题。不过这并不能阻止我继续折腾下去! 图片压缩 在如今这个手机普遍千万像素的时代,一张照片动辄5M的大小。作为一个良心的开发者,我们是要为用户的流量负责的。 该怎么做?我也不知道。大家都在用canvas实现,我也就用了。
1 2 3 4 5 6 7 8 9 10 11 12 |
document.getElementById('file').addEventListener('change', function() { var reader = new FileReader(); reader.onload = function (e) { compress(this.result); }; reader.readAsDataURL(this.files[0]); }, false); |
不管文件域是用何种方式打开的,都可以在 change 事件中获取到选择的文件或拍摄的照片。 创建一个FileReader对象,我们需要调用readAsDataURL把文件转换为base64图像编码,如data:image/jpeg;base64……这种格式。 onload是一个异步回调,当文件读取完执行该方法内代码。this.result记录读取结果,如果读取失败,该值为null。在这里进行图片压缩的具体操作。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
var compress = function (res) { var img = new Image(), maxH = 160; img.onload = function () { var cvs = document.createElement('canvas'), ctx = cvs.getContext('2d'); if(img.height > maxH) { img.width *= maxH / img.height; img.height = maxH; } 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 dataUrl = cvs.toDataURL('image/jpeg', 0.6); // 上传略 } img.src = res; } |
创建一个Image对象,给src属性赋值为读取结果,同样在onload异步回调中编写处理图片的代码。 这里就要开始使用canvas进行图片压缩了。 首先是尺寸按比例缩放,然后把图片绘到画布上,最后调用toDataURL方法压缩图像质量。
1 2 |
context.toDataURL('MIME类型', 图像质量0-1); // 该方法返回base64图像编码 |
代码里省略了一些校监操作,如文件类型约束和文件大小判断(小于一定值可以不压缩)。 最后就是把数据发送到后端的操作,这里就不说了。 Html5调用摄像头 通过以上的代码已经可以实现调用手机相机拍照、压缩、上传这一整套流程了。 不过在折腾的过程中也发现了一种调用摄像头的方法。注意,是摄像头!使用input调用的是相机。其中的差别就是摄像头是只捕获画面,相机还包括原生的一些拍照、设置等控件。 通过对摄像头的调用可以做很多有趣的事,比如拍照美化、滤镜等。可以说实现一个第三方相机是没问题的。 之前下载过一款安卓相机APP,不到100K的大小,可以实现拍照的一些风格化,也许就是Html5实现的呢。 需要用到的是 getUserMedia API,具体的实现这里就不贴了。 from:http://www.imys.net/20150916/webapp-input-use-camera.html
View Details整理时下流行的浏览器User-Agent大全
总结整理时下流行的浏览器User-Agent大全 此文章转至:http://www.360doc.com/content/12/1012/21/7662927_241124973.shtml 用于学习 一、基础知识篇: Http Header之User-Agent User Agent中文名为用户代理,是Http协议中的一部分,属于头域的组成部分,User Agent也简称UA。它是一个特殊字符串头,是一种向访问网站提供你所使用的浏览器类型及版本、操作系统及版本、浏览器内核、等信息的标识。通过这个标 识,用户所访问的网站可以显示不同的排版从而为用户提供更好的体验或者进行信息统计;例如用手机访问谷歌和电脑访问是不一样的,这些是谷歌根据访问者的 UA来判断的。UA可以进行伪装。 浏览器的UA字串的标准格式:浏览器标识 (操作系统标识; 加密等级标识; 浏览器语言) 渲染引擎标识版本信息。但各个浏览器有所不同。 字串说明: 1、浏览器标识 出于兼容及推广等目的,很多浏览器的标识相同,因此浏览器标识并不能说明浏览器的真实版本,真实版本信息在 UA 字串尾部可以找到。 2、操作系统标识 3、加密等级标识 N: 表示无安全加密 I: 表示弱安全加密 U: 表示强安全加密 4、浏览器语言 在首选项 > 常规 > 语言中指定的语言 5、渲染引擎 显示浏览器使用的主流渲染引擎有:Gecko、WebKit、KHTML、Presto、Trident、Tasman等,格式为:渲染引擎/版本信息 6、版本信息 显示浏览器的真实版本信息,格式为:浏览器/版本信息 浏览器User-Agent的详细信息 PC端: safari 5.1 – MAC User-Agent:Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50 safari 5.1 – Windows User-Agent:Mozilla/5.0 (Windows; U; Windows NT 6.1; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 […]
View DetailsUber 从 Postgres 切换到 MySQL
Uber工程师在官方博客上描述了他们为什么要从 Postgres 切换到 MySQL 数据库。Uber的早期架构是由 Python编写的后端应用构成,使用了 Postgres 数据库。但此后,Uber的架构发生了显著的改变,转变到了微服务模型和新的数据平台。以前他们使用 Postgres,现在则改用了基于 MySQL 的数据库分片层。Uber工程师称他们之所以切换到Schemaless和其它基于 MySQL 的后端服务,最主要的原因是Postgres 数据复制效率低下,Postgres更新已有行的效率低于 MySQL,Postgres需要重写每一个行索引,而MySQL只更新改变的索引。 相关链接 MySQL 的详细介绍:请点这里 MySQL 的下载地址:请点这里 from:http://www.oschina.net/news/75638/uber-mysql-migration
View DetailsLastPass 曝 0day 漏洞,账号能被恶意网站访问
Google Project Zero 黑客 Tavis Ormandy 报告在流行密码管理工具 LastPass 中发现了一个高危0day 漏洞,允许恶意网站完整访问用户的账号。漏洞已经报告给了 LastPass,细节没有披露。巧合的是另一位安全研究人员 Mathias Karlsson 也报告了 LastPass 的一个类似漏洞,目前还不清楚两个漏洞是否相同。 Karlsson 在其博客上描述了他的发现:LastPass的密码自动填写功能存在bug,允许恶意网站欺骗 LastPass 相信它是另一个网站比如Twitter,窃取用户登录凭证。Karlsson建议用户关闭自动填写功能。LastPass称它已经修复了漏洞,漏洞主要影响 Firefox 用户。 相关链接 Lastpass 的详细介绍:请点这里 Lastpass 的下载地址:请点这里 from:http://www.oschina.net/news/75639/lastpass-0day-bug
View DetailsIEEE Spectrum 编程语言最新排行:大数据是赢家
一年一度的IEEE Spectrum编程语言排行盛宴又来了,来看看今年7月26日发布的前十名榜单。这个排行榜已经进行了三年。IEEE Spectrum的排序是来自10个重要数据源的综合,例如 IEEE Xplore, GitHub, CareerBuilder 等等,他们根据数据源对48种语言给出不同角度的排列。调整不同的权重,可以得到不同的排序结果。用户甚至可以根据自己的情况,调整权重,得到相应的排序 结果。 感兴趣的朋友可以点击这个链接进入网站查看结果:Interactive: The Top Programming Languages 2016。 我们来对比一下去年和今年的前十榜单(左边2016年,右边2015年),看看这一年的趋势。 可 以发现,C取代Java成为第一名,Python和C++换了位置,C和R换了位置,PHP和JavaScript保持原来的位置不动。另外,需要重点提 出的是,2016年第十名出现了新的角色:Go,Go原来在去年榜中排第13位,而去年第10名的Matlab在今年榜中位居第14名。 总体而言,仅就前10名来看,上升的语言有:C、Python、R和Go。 纵观整个48种语言此起彼伏的发展势头,参与排行榜制作的Nicholas Diakopoulos撰文表示,与大数据相关的语言普遍存在上升趋势,比如Go、Julia、R、Scala甚至是Python。 榜 单前十名的竞争是最为激烈的。谷歌的Go前年第19名,去年第13名,今年更是挤进前10,充分说明了其日益增长的影响力。Diakopoulos分析 说,Go的快速上升跟Github上的使用率上升有关。据统计,2016年Github上以Go为主要语言的的原始仓库数量是2014年的四倍,另外在 Reddit上人们对Go的讨论也较多,如今有关Go的帖子比2014年翻了三倍。 专 门用于数据统计分析的R语言排名一路飙升,从14年的第13名,到15年的第6名,再到今年的第5名。但是R语言最重要的一点,是它在学术研究论文中被提 及的次数显著上升。IEEE Xplore是收录了数百万的学术论文、行业标准和专著的权威数据库,这个排行榜也给IEEE Xplore的数据源以较大权重。数据显示,2015年IEEE Xplore中仅有39篇论文讨论R语言,今年相关论文数量达到了244篇。 而Scala从前年第18名升至今年15名,Julia 从去年40名跃升至今年的33名。 在 招聘市场的权重里,虽然Java 和Python一直在人才市场中居于霸主地位,但Diakopoulos表示雇主们对于R和Scala的兴趣明显在上升。2014年招聘网站 CareerBuilder和Dice上所列的R和Scala相关工作只有136个,但到2016年这一数量翻了四倍,达到631个。 榜单一定程度上反映了学术和市场趋势,读者可以根据自己的实际情况来参考,来规划自己的学术和职业发展方向。 稿源:雷锋网 from:http://www.oschina.net/news/75640/ieee-spectrum-latest-rank
View Details阿里巴巴分布式数据库同步系统 otter
otter 基于数据库增量日志解析,准实时同步到本机房或异地机房的mysql/oracle数据库. 一个分布式数据库同步系统。 工作原理: 原理描述: 1. 基于Canal开源产品,获取数据库增量日志数据。 什么是Canal, 请点击 2. 典型管理系统架构,manager(web管理)+node(工作节点) a. manager运行时推送同步配置到node节点 b. node节点将同步状态反馈到manager上 3. 基于zookeeper,解决分布式状态调度的,允许多node节点之间协同工作. osc地址:http://www.oschina.net/p/otter
View DetailsPHP 图像处理库 Grafika
Grafika 是一个 PHP 的图像处理库。可用于改变图像大小、剪切、比较,以及添加水印等操作。同时可以创建一些文本图片、几何图形并应用一些过滤器。基于 Imagick 和 GD 构建。 特征 智能裁剪 图像比较 感知哈希 高级图像处理过滤器 贝塞尔曲线 示例代码: ? 1 2 3 4 5 6 7 useGrafika\Grafika; $editor= Grafika::createEditor(); $editor->open( "path/to/jpeg/image.jpg"); $editor->resizeExact( 200, 200 ); $editor->save( "path/to/edited.jpg", null, 90 ); osc地址:http://www.oschina.net/p/grafika
View DetailsIncorrect string value: '\xF0\x90\x8D\x83…' for column… Emoji表情字符过滤的Java实现
Emoji表情字符现在在APP已经广泛支持了。但是Mysql的UTF8编码对Emoji字符的支持却不是那么好。所以我们经常会遇到这样的异常: Incorrect string value: '\xF0\x90\x8D\x83…' for column 原因是Mysql里UTF8编码最多只能支持3个字节,而Emoji表情字符使用的UTF8编码,很多都是4个字节,有些甚至是6个字节。 解决的方案有两种: 1.使用utf8mb4的mysql编码来容纳这些字符。 2.过滤掉这些特殊的表情字符。 关于第一种解决方法,请参考:http://segmentfault.com/a/1190000000616820 和 http://info.michael-simons.eu/2013/01/21/java-mysql-and-multi-byte-utf-8-support/ 有大量细节需要注意,例如:mysql版本,mysql的配置,mysql connector的版本等等。。 因为我们使用的云数据库,所以我选择了过滤这些特殊字符。其实过滤的方式很简单,直接使用正则表达式匹配编码范围,然后替换就行了。 下面是我的代码。 更多可以参考:http://stackoverflow.com/questions/27820971/why-a-surrogate-java-regexp-finds-hypen-minus import org.apache.commons.lang3.StringUtils; public class EmojiFilterUtils { /** * 将emoji表情替换成* * * @param source * @return 过滤后的字符串 */ public static String filterEmoji(String source) { if(StringUtils.isNotBlank(source)){ return source.replaceAll("[\\ud800\\udc00-\\udbff\\udfff\\ud800-\\udfff]", "*"); }else{ return source; } } public static void main(String[] arg ){ try{ String text = "This is a smiley \uD83C\uDFA6 face\uD860\uDD5D \uD860\uDE07 \uD860\uDEE2 \uD863\uDCCA \uD863\uDCCD \uD863\uDCD2 \uD867\uDD98 "; System.out.println(text); System.out.println(text.length()); System.out.println(text.replaceAll("[\\ud83c\\udc00-\\ud83c\\udfff]|[\\ud83d\\udc00-\\ud83d\\udfff]|[\\u2600-\\u27ff]", "*")); System.out.println(filterEmoji(text)); }catch (Exception ex){ ex.printStackTrace(); } } } from:http://blog.csdn.net/shootyou/article/details/44852639
View Details |"|&|<|>等html字符转义
No. 文字表記 10進表記 16進表記 文字 Comment 001 " " " """ quotation mark = APL quote 002 & & & "&" ampersand 003 < < < "<" less-than sign 004 > > > ">" greater-than sign 005     " " no-break space = non-breaking space iSO 8859-1 characters char glyph HTML tag ¡ ¡ ¢ ¢ £ £ ¤ ¤ ¥ ¥ ¦ ¦ § § ¨ ¨ © © ª ª « « ¬ ¬ ­ ® ® ¯ ¯ ° ° ± ± […]
View Details用node.js进行微信公众平台的开发
基本原理 用nodejs怎样来实现对微信公众平台的开发呢? 别的就不多说了,先来简单介绍微信公众平台的基本原理。 微信服务器就相当于一个转发服务器,终端(手机、Pad等)发起请求至微信服务器,微信服务器,然后将请求转发给自定义服务(这里就是我们的具体实现)。服务处理完毕,然后转发给微信服务器,微信服务器再将具体响应回复到终端;通信协议为:HTTP;数据格式为:XML。 具体的流程如下图所示: 其实,我们需要做的事情,就是对HTTP请求,做出响应。具体的请求内容,我们按照特定的XML格式去解析,处理完毕后,也要按照特定的XML格式返回。 平台注册 要想完成对微信公众平台的开发,我们需要注册一个微信公众平台帐号。注册步骤如下: 打开微信公共平台的官网,https://mp.weixin.qq.com/,点击“立即注册”。 然后根据提示,填写基本信息,邮箱激活,选择类型,信息登记,公众号信息,完成注册。 在注册完成以后,我们要对公众号进行一些基本的设置。登录公众号,找到【公众号设置】,然后设置头像以及其它信息。 nodejs环境搭建 我们需要在公网上找一台服务器,以便可以启动我们的nodejs的环境,启动环境后通过设置访问地址,我们就可以接收微信服务器发送的消息了,并且我们也可以向微信服务器发送消息了。 在公网的服务器中安装完成nodejs以后,我们还需要安装一些nodejs所用到的模块,如:express,node-xml,jssha等模块。可以通过npm命令进行安装。 我们通过nodejs来实现向微信服务器消息的发送与接收,以及与微信服务器的签名认证。 在我们右面的编辑环境中已经为同学们安装了nodejs环境。我们在接下来内容中就为同学们来实现微信服务器的签名认证。 创建express框架 我们在前面的课程中已经安装了express模块,并且在我们右面的环境中已经创建了一个名为app.js的文件。现在我们就在这个文件中完成express框架。如下代码:
1 2 3 4 5 6 7 8 9 10 11 12 |
<span class="hljs-keyword">var</span> express = <span class="hljs-built_in">require</span>(<span class="hljs-string">"express"</span>); <span class="hljs-keyword">var</span> path=<span class="hljs-built_in">require</span>(<span class="hljs-string">'path'</span>); <span class="hljs-keyword">var</span> app = express(); server = <span class="hljs-built_in">require</span>(<span class="hljs-string">'http'</span>).Server(app); app.set(<span class="hljs-string">'views'</span>,__dirname); <span class="hljs-comment">// 设置视图 </span> app.set(<span class="hljs-string">'view engine'</span>, <span class="hljs-string">'html'</span>); app.engine( <span class="hljs-string">'.html'</span>, <span class="hljs-built_in">require</span>( <span class="hljs-string">'ejs'</span> ).__express ); <span class="hljs-built_in">require</span>(<span class="hljs-string">'./index'</span>)(app); <span class="hljs-comment">//路由配置文件</span> server.listen(<span class="hljs-number">80</span>,<span class="hljs-function"><span class="hljs-keyword">function</span>()</span>{ <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'App start,port 80.'</span>); }); |
然后再添加一个名为test.html的文件。写入以下内容
1 2 3 4 5 6 7 8 9 10 11 |
<span class="xml"><span class="hljs-meta"><!DOCTYPE html></span> <span class="hljs-tag"><<span class="hljs-name">html</span>></span> <span class="hljs-tag"><<span class="hljs-name">head</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</span>></span> <span class="hljs-tag"><<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span>></span> <span class="hljs-tag"><<span class="hljs-name">title</span>></span>汇智网<span class="hljs-tag"></<span class="hljs-name">title</span>></span> <span class="hljs-tag"></<span class="hljs-name">head</span>></span> <span class="hljs-tag"><<span class="hljs-name">body</span>></span> <span class="hljs-tag"><<span class="hljs-name">div</span>></span><span class="hljs-tag"><<span class="hljs-name">%=</span></span></span><span class="ruby">issuccess</span><span class="xml"><span class="hljs-tag">%></span><span class="hljs-tag"></<span class="hljs-name">div</span>></span> <span class="hljs-tag"></<span class="hljs-name">body</span>></span> <span class="hljs-tag"></<span class="hljs-name">html</span>></span> </span> |
我们还要添加一个名为index.js的文件,来实现我们的路由。点击编辑环境中的添加文件按钮,添加文件,然后我们写入以下代码,其中GET请求用来验证配置的URL合法性,POST请求用来处理微信消息。
1 2 3 4 5 6 7 8 |
<span class="hljs-built_in">module</span>.exports = <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(app)</span></span>{ app.get(<span class="hljs-string">'/'</span>,<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(req,res)</span></span>{ res.render(<span class="hljs-string">'test'</span>,{issuccess:<span class="hljs-string">"success"</span>}) }); app.get(<span class="hljs-string">'/interface'</span>,<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(req,res)</span></span>{}); app.post(<span class="hljs-string">'/interface'</span>,<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(req,res)</span></span>{}); } |
这样我们需要的express框架就完成了,当然我们还可以添加public公共文件夹以及我们要用到的中间件。保存文件,点击【提交运行】,然后点击【访问测试】,去试试吧。记下访问测试的地址,我们将在下一节中会用到该地址。 微信服务器配置 我们登录微信公众平台,在开发者模式下面找到基本配置,然后修改服务器配置。如图所示: 首先URL要填写公网上我们安装nodejs接收与发送数据的路径。我们可以填写上节中【访问测试】的地址,然后加上对应的路由就可以了。
1 2 |
<span class="hljs-string">http:</span><span class="hljs-comment">//724515db515222a9efffd6b092aa955d.me.hubwiz.com/interface</span> |
上面代码是我的访问测试的地址,然后加上前面课程中的路由,同学们要根据自己的访问测试地址与路由来填写。 Token要与我们自定义服务器端的token一致。填写完成以后,就可以点击提交了,在提交以前,我们启动app.js(点击【提交运行】)。这样根据我们的路由匹配就可以验证签名是否有效了。 当配置完成以后,一定要启用配置。 网址接入 公众平台用户提交信息后,微信服务器将发送GET请求到填写的URL上,并且带上四个参数:
1 2 3 4 5 6 |
参数 描述 signature 微信加密签名 timestamp 时间戳 nonce 随机数 echostr 随机字符串 |
开发者通过检验signature对请求进行校验(下面有校验方式)。若确认此次GET请求来自微信服务器,请原样返回echostr参数内容,则接入生效,否则接入失败。 signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。 加密/校验流程: 将token、timestamp、nonce三个参数进行字典序排序; 将三个参数字符串拼接成一个字符串进行sha1加密; 开发者获得加密后的字符串可与signature对比,标识该请求来源于微信。 参数排序 首先我们确认请求是来自微信服务器的get请求,那么就可以在index.js文件中进行添加代码了。然后在app.get('/interface',function(req,res){});的function中进行添加。 先来获取各个参数的值,如下代码:
1 2 3 4 5 6 |
<span class="hljs-keyword">var</span> token=<span class="hljs-string">"weixin"</span>; <span class="hljs-keyword">var</span> signature = req.query.signature; <span class="hljs-keyword">var</span> timestamp = req.query.timestamp; <span class="hljs-keyword">var</span> echostr = req.query.echostr; <span class="hljs-keyword">var</span> nonce = req.query.nonce; |
我们在这里对token进行设置,让其与微信服务器中设置的token一致。 然后对其中的token、timestamp、nonce进行排序,如下代码:
1 2 3 4 5 6 |
<span class="hljs-keyword">var</span> oriArray = <span class="hljs-keyword">new</span> <span class="hljs-keyword">Array</span>(); oriArray[<span class="hljs-number">0</span>] = nonce; oriArray[<span class="hljs-number">1</span>] = timestamp; oriArray[<span class="hljs-number">2</span>] = token; oriArray.sort(); |
这样我们就完成了排序。 参数加密 在上节中我们已经对参数进行了排序,然后我们在这一节中要将参数组成一个字符串,进行SH-1加密。在加密以前要用到jssha模块,在我们的文件中要引用该模块。
1 2 |
<span class="hljs-keyword">var</span> jsSHA = <span class="hljs-keyword">require</span>(<span class="hljs-string">'jssha'</span>); |
在上一节课中我们已经对参数排序完成,并存放在数组中,我们可以通过join方法来生成一个字符串,如下代码:
1 2 |
<span class="hljs-keyword">var</span> original = oriArray.<span class="hljs-keyword">join</span>(<span class="hljs-string">''</span>); |
最后对该数据进行加密,如下代码:
1 2 3 4 |
<span class="hljs-keyword">var</span> jsSHA = <span class="hljs-keyword">require</span>(<span class="hljs-string">'jssha'</span>); <span class="hljs-keyword">var</span> shaObj = <span class="hljs-keyword">new</span> jsSHA(original, <span class="hljs-string">'TEXT'</span>); <span class="hljs-keyword">var</span> scyptoString=shaObj.getHash(<span class="hljs-string">'SHA-1'</span>, <span class="hljs-string">'HEX'</span>); |
好了这样就生成了我们需要的签名字符串scyptoString。 签名对比 我们已经得到了我们想要的签名字符串scyptoString,然后我们就可以与来自微信服务器的签名进行对比了,对比通过,则我们就可以接收与发送消息了。
1 2 3 4 5 6 |
<span class="hljs-selector-tag">if</span>(signature == scyptoString){ <span class="hljs-comment">//验证成功</span> } <span class="hljs-selector-tag">else</span> { <span class="hljs-comment">//验证失败</span> } |
本参考了如下网站,更多内容也请访问: http://www.hubwiz.com/course/569dc7fdacf9a45a69b051cd/ from:http://my.oschina.net/u/2275217/blog/630770
View Details