阿里前端学习笔记(二)

2014-07-20 by niuzhixiang

Kissy

Hello World

  • 引入Kissy种子文件

    1. <script src="http://g.tbcdn.cn/kissy/k/1.4.4/seed.js"></script>
  • 添加一个Kissy模块

    1. //此处省略模块名称,默认为该模块所在JS文件名。建议采用此写法,一个JS文件中只定义一个模块
    2. //回调函数的第一个参数为KISSY本身;第二个参数为Base模块,与requires数组中指定的“base”相对应
    3. KISSY.add(function(S,Base) {
    4. //HelloWorld就是该模块类,它继承自Base模块(类)
    5. var HelloWorld = Base.extend({
    6. initializer:function(){
    7. var self = this;
    8. // Your Code
    9. alert('hello world');
    10. }
    11. },{
    12. ATTRS: {
    13. // 这里是初始参数和默认值
    14. A:{
    15. value:'abc'
    16. }
    17. }
    18. });
    19. //返回HelloWorld类
    20. return HelloWorld;
    21. },{
    22. //声明该模块依赖的其他模块
    23. requires:['base']
    24. });
  • 使用这个Kissy模块

    1. //使用模块时需指定模块名称
    2. KISSY.use('h5-2banner-active/mods/banner/index',function(S,Banner){
    3. //创建HelloWorld模块的实例,会执行initializer()方法。
    4. new HelloWorld();
    5. });

Kissy的特性

  • 高度模块化。通过KISSY.add()注册一个模块,通过KISSY.use()使用一个模块,便于KISSY组件的重用。
  • 很多API与jQuery类似。

Kissy常用模块

  • Seed模块:内置于种子文件Seed中,包括基础的面向对象支持、模块加载器(loader模块)、UA特性检测(UA模块)、全局工具函数(lang模块)等核心的功能。
  • Components模块:包含一些比较常用的模块,例如动画效果(anim模块)、DOM节点操作(domnode模块,其中后者继承自前者,进行了进一步的封装)、AJAX(io模块)、事件机制(event模块)等。
  • Widgets模块:由官方或非官方提供的其他组件模块。

参考资料

Kissy官方网站

Juicer

简介

Juicer是一个轻量级的JS模板引擎。它将数据和模板分离,通过把数据渲染到模板来生成最终的HTML片段。Juicer可以在NodeJS环境中运行。

Demo

  1. <!--数据-->
  2. <!--#def
  3. {
  4. "tmsTitle": "LOGO",
  5. "title": "测试图片",
  6. "href": "http://gtms01.alicdn.com/tps/i1/T1QBDWFXxcXXXzCwr6-168-170.png"
  7. }
  8. -->
  9. <!--模板-->
  10. 图片地址: ${title} <br />
  11. 链接地址: ${href}
  12. <!--数据-->
  13. <!--#def
  14. {
  15. "list": [
  16. {
  17. "qt": "机票分会场",
  18. "dz": "http://trip.taobao.com/jipiao"
  19. },
  20. {
  21. "qt": "酒店分会场",
  22. "dz": "http://trip.taobao.com/jiudian"
  23. },
  24. {
  25. "qt": "度假分会场",
  26. "dz": "http://trip.taobao.com/dujia"
  27. }
  28. ],
  29. "tmsTitle": "分会场列表"
  30. }
  31. -->
  32. <!--模板,使用了循环语法-->
  33. <ul class="other-link">
  34. {@each list as item}
  35. <li class="other-link-item"><a href="${item.dz}" target="_blank">${item.qt}</a></li>
  36. {@/each}
  37. </ul>

经过grunt-tpl-compiler编译后生成的HTML代码(遵循Kissy模块规范)为:

  1. <!--第一段数据和模板渲染出来的HTML代码-->
  2. 图片地址: 测试图片
  3. <br />链接地址: http://gtms01.alicdn.com/tps/i1/T1QBDWFXxcXXXzCwr6-168-170.png
  4. <!--第二段数据和模板渲染出来的HTML代码-->
  5. <ul class="other-link">
  6. <li class="other-link-item">
  7. <a href="http://trip.taobao.com/jipiao" target="_blank">机票分会场</a>
  8. </li>
  9. <li class="other-link-item">
  10. <a href="http://trip.taobao.com/jiudian" target="_blank">酒店分会场</a>
  11. </li>
  12. <li class="other-link-item">
  13. <a href="http://trip.taobao.com/dujia" target="_blank">度假分会场</a>
  14. </li>
  15. </ul>

参考资料

Juicer官方网站

Less

简介

Less是一个CSS预编译器,它是原生CSS语言的扩展,添加了诸如变量、函数、运算、规则嵌套等新功能。Less可以在NodeJS环境中运行。

Demo

Less代码:

  1. /*此处声明一个变量base*/
  2. @base: #f938ab;
  3. /*此处自定义了一个函数,如果第二个参数是一个颜色值,则调用该函数*/
  4. .box-shadow(@style, @c) when (iscolor(@c)) {
  5. -webkit-box-shadow: @style @c;
  6. box-shadow: @style @c;
  7. }
  8. /*此处又自定义了一个同名的函数,如果第二个参数是一个数字,则调用该函数。该函数首先
  9. 将第二个参数(alpha值)转换成rgba颜色值,然后再调用上面那个自定义函数*/
  10. .box-shadow(@style, @alpha: 50%) when (isnumber(@alpha)) {
  11. .box-shadow(@style, rgba(0, 0, 0, @alpha));
  12. }
  13. .box {
  14. /*此处使用了一个内置函数saturate(),用于增加一定数值的颜色饱和度。Less中提供了
  15. 大量这种很有用的函数*/
  16. color: saturate(@base, 5%);
  17. /*此处使用了一个内置函数lighten(),用于增加一定数值的颜色亮度。*/
  18. border-color: lighten(@base, 30%);
  19. /*此处使用了规则的嵌套,在.box规则中嵌套了一个div规则,并且在div规则中使用了自定
  20. 义的函数,由于第二个参数是一个数字值而非颜色值,因此调用的是第二个自定义函数*/
  21. div { .box-shadow(0 0 5px, 30%) }
  22. }

编译后的CSS代码:

  1. .box {
  2. color: #fe33ac;
  3. border-color: #fdcdea;
  4. }
  5. .box div {
  6. -webkit-box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
  7. box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
  8. }

参考资料

Less CSS 官方网站

航旅桥协议

简介

  • 航旅桥协议是由航旅客户端工程师开发的一套标准协议,用于H5页面与native代码的通信。在Bridge JS文件中实现了这套桥协议。
  • 协议一共有三类,page://native://bridge://。其中page协议用于H5与native页面之间的跳转;native协议用于H5页面与native代码的数据交换(例如通过本地代码获取地理位置数据);bridge协议包含除page和native外的其他所有协议(例如获取手机网络连接情况、响铃及振动情况等)。
  • 桥协议JS文件(Bridge项目下的index.js)的核心API是pushBack()方法,各个协议的实现方法都调用了pushBack()方法。

参考资料

详见阿里航旅前端Wiki页面。

NodeJS

简介

NodeJS是一个脱离了浏览器的JavaScript运行环境,可以独立运行JS程序。NodeJS的核心思想有两点——事件机制和异步处理。JavaScript语言很好地实现了这两点,使得NodeJS更加高效。

模块化

编写大型程序时都需要将代码模块化,NodeJS中的模块化机制包括require()函数、exports对象和module对象。

  • require()用于在当前模块中加载并使用别的模块。例如:

    1. var mymodule = require(./mymodule)

    该语句在当前模块中引入了同级目录下的mymodule.js模块。

  • exports对象是当前对象的导出对象。其他模块通过require()函数引用当前模块时,得到的就是exports对象。
  • module对象用于获取当前模块本身的相关信息。最常用的是替换当前模块的导出对象exports,例如以下语句,将一个模块的导出对象设置为了一个函数:

    1. module.exports = function () {
    2. console.log('Hello World!');
    3. };

NPM

NPM是NodeJS自带的包管理工具,类似于Linux下的rpm。使用NPM可以从NPM服务器下载别人编写的第三方包。例如下载grunt工具(v0.4.1)的命令如下:

  1. $ npm install grunt@0.4.1

文件操作

NPM提供了对于本地文件操作的API。这些API底层大都是C/C++异步实现的。以下示例是一个拷贝文件的Demo:

  1. //引入文件操作的内置模块fs
  2. var fs = require('fs');
  3. //调用fs模块提供的API实现文件的拷贝
  4. function copy(src, dst) {
  5. fs.writeFileSync(dst, fs.readFileSync(src));
  6. }
  7. //在主程序中调用文件拷贝函数
  8. function main(argv) {
  9. copy(argv[0], argv[1]);
  10. }
  11. /*使用process.argv可以获取到命令行参数,而前两个命令行参数分别是NodeJS执行程序
  12. 的绝对路径,以及主模块的绝对路径。因此从第三个命令行参数开始才是用户输入的。
  13. 这样就可以在命令行输入copy [src] [dst]这样的命令来调用该模块,实现文件拷贝了*/
  14. main(process.argv.slice(2));

网络操作

NodeJS提供了一整套网络编程的API,主要包括几个部分:作为客户端向服务器发起HTTP请求;作为服务端接收客户端的HTTP请求;实现Socket通信(使用net模块);解析URL及URL参数等(使用urlquerystring模块)。以下两个例子分别展示了NodeJS作为客户端和服务器进行HTTP通信的过程。

  • 作为客户端,向服务器发送HTTP请求,使用内置的http模块:

    1. //定义请求头信息
    2. var options = {
    3. hostname: 'www.example.com',
    4. port: 80,
    5. path: '/upload',
    6. method: 'POST',
    7. headers: {
    8. 'Content-Type': 'application/x-www-form-urlencoded'
    9. }
    10. };
    11. //定义请求request,并传入响应到来时的回调函数
    12. var request = http.request(options, function (response) {});
    13. //写入请求数据,发送请求
    14. request.write('Hello World');
    15. //请求结束
    16. request.end();
  • 作为服务端,接收客户端发来的HTTP请求,也使用内置的http模块:

    1. /*创建一个HTTP服务器,并传入请求到来时的回调函数。每当一个请求到来时,该回调
    2. 函数就会被执行一次。这是一种事件机制。*/
    3. http.createServer(function (request, response) {
    4. //设置响应头信息
    5. response.writeHead(200, { 'Content-Type': 'text/plain' });
    6. //返回响应数据
    7. request.on('data', function (chunk) {
    8. response.write(chunk);
    9. });
    10. //响应结束
    11. request.on('end', function () {
    12. response.end();
    13. });
    14. //该HTTP服务器监听80端口
    15. }).listen(80);

进程管理

NodeJS可以管理自身进程,也可以创建子进程,分别通过process全局对象和child_process模块来实现。例如通过process.argv获取命令行参数(属于当前进程),通过child_process.exec()方法来调用终端命令(终端命令运行在子进程)。

异步编程

在NodeJS中,异步编程与同步编程最大的区别就是:异步编程采用回调方式来实现功能。NodeJS提供的异步API也都是采用回调的方式实现的。例如使用一个函数的输出作为另一个函数的输入,同步编程的写法是:

  1. //把函数fn2()的输出作为函数fn1()的输入
  2. var output = fn1(fn2('input'));
  3. // Do something.

而异步编程的写法是:

  1. //把函数fn2()的输出作为函数fn1()的输入
  2. fn2('input', function (output2) {
  3. fn1(output2, function (output1) {
  4. // Do something.
  5. });
  6. });

可以看出,异步编程一般就是一个回调函数套一个回调函数的>形状。这种异步编程模式在遍历数组、异常处理等方面应用较多。

参考资料

Web前端安全

SQL注入攻击

SQL注入攻击就是攻击者作为用户,在发送URL或填写表单时,恶意传递或输入特定的SQL语句,从而达到查询或篡改数据库的目的。例如一个正常的请求url为http://www.abc.com/home?userid=1,服务端接收到请求参数后会运行如下查询语句SELECT * FROM user WHERE userid = 1,而如果攻击者发送的请求url为http://www.abc.com/home?userid=1 or 1=1,则服务端运行的SQL语句就变成SELECT * FROM user WHERE userid = 1 or 1=1,这样攻击者就可以获取到user表中所有的数据,造成用户信息泄露。

XSS攻击

XSS即跨站脚本攻击(Cross Site Scripting),原理与SQL注入攻击类似,也是攻击者作为用户,恶意传递或输入一些特定的JS脚本语句,从而进行钓鱼等活动。详细攻击方式请谷歌一下。

总结

谨记两点——“永远不要相信用户输入的数据”和“永远不要相信服务端响应的数据”,在处理用户的输入数据和服务端的响应数据之前,一定要先做好验证和转码等工作,防止遭到攻击。

杂七杂八的东西

markdown

挺好用的一种博客编辑语言,与Github完美配合,让周记写的更爽了。

抓包工具

Charles或者Fiddler,基于代理进行抓包,比Chrome的Network工作台更强大。

问题解决

  • 在公司本机上运行grunt awpp任务时总是出现乱码错误,索性在GruntFile.js中加了一句console.log(),把awpp任务封装的命令打印出来,然后直接执行这条命令就ok了。
  • grunt tpl_compiler执行失败的问题神奇地消失了,估计是之前没有装好tpl的原因吧。