学习和使用Github API

入门

  • https://api.github.com/users/wangyuzju获取wangyuzju的用户信息

认证

认证时,请求的权限对应的参数

参数与权限对应关系

学习笔记

获得指定branch下的内容

查遍github API的说明文档,没有发现GET方法能获取指定分支下的内容。观察获取内容APIhttps://api.github.com/repos/wangyuzju/blog/contents返回的内容,发现默认的文件下面会带上?ref=master,原来GitHub通过ref属性来指定分支返回内容,试了一下https://api.github.com/repos/wangyuzju/blog/contents?ref=gh-pages果然可以!

关于CORS

github大部分api是支持cors的,也就是可以直接GET或者POST获取返回数据,但是在用户认证这块却是不支持CORS的。因此需要合理地进行设计,才能实现GitHub的全部API。

补充,最初提交client_idclient_secretcode(访问https://github.com/login/oauth/authorize?client_id=bfaa94b476a91ae70830之后github回调页面时传入的参数code?=XXX)至https://github.com/login/oauth/access_token时,是不支持CORS的,因为github API不允许将clientid和clientsecret暴露出来,获取accesstoken这个链接如果支持CORS意味着信息硬编码到JS文件中,都暴露了,因此github**不支持提供accesstoken页面的CORS调用**,而获得access_token之后,访问其他链接就都支持CORS调用了

解决办法: 将oauth的回调处理放到服务器上,利用服务器去验证并获得accesstoken,然后传给我的博客,再通过accesstoken完成认证 --!

[2013-05-10]

基于MVC的JavaScript Web富应用开发

CH1 MVC和类

CH2 事件和监听

window.onload和DOMContentLoaded

window.onload是页面所有资源(图像,CSS等)加载完毕才会触发,DOMContentLoaded则是 当DOM构建完成时触发。jQuery增加的ready()函数就是在后者不可用时,使用前者,主流 类库的处理方法参见这里

$.delegate()实现事件委托

使用事件委托的方式,在事件注册时候增加的子元素也能触发事件回调。

$.trigger()可以触发自定义事件

使用$.bind()注册自定义事件的回调函数之后,使用$.trigger()触发自定义事件, 自定义事件会沿着DOM数做冒泡

其他

还介绍了发布者/订阅者模式

CH3 模型和数据

模型应当从视图和控制器中解耦出来,与数据操作和行为相关的逻辑都应当放入模型中,通过 命名空间进行管理。

ORM 对象关系映射

ORM(Object-relational mapper)可以用来做数据管理及用作模型,使用ORM可以将模型和 远程服务捆绑在一起,任何模型实例的变化都会在后台发起AJAX请求。使用ORM来抽象JS数据 类型,通过添加自定义的函数和属性来增强基础数据的功能,比如数据验证,监听,数据 持久化及服务器端回调处理,以提高代码重用率。

原型继承

Object.create(originObject),返回新对象的原型为传入的这个参数对象,其原理如下:

if (typeof Object.create != "function"){
    Object.create = function(o){
        function F(){};
        F.prototype = o;
        return new F();
    };
}

原型继承的实现

[2013-05-09]

Twitter的前端工程师招聘要求

Bootstrap这么火,让人不得不对Twitter的工程师产生钦佩,紧跟国际化脚步,看看人家前端工程师都具备哪些能力 查看原文

Requirements

  • You have previous experience architecting a full featured client application using Javascript. This is a MUST. If you have figured out how to bring stuff like Coffeescript and Backbone into the mix, you are probably just as serious as we are about using the best technology available.
  • You’re an expert in object-oriented Javascript, HTML, and CSS - able to create elegant and maintainable code from mock ups.
  • You are ready to aggressively push your code out to our customers day one, and you are committed to building a flawless customer experience. We are a team with a passion for great user experiences on mobile and the web, and want to work with someone that makes this a priority.
  • You want to play a lead role in building a beautiful application used by thousands of mobile developers around the world.
  • You’re smart, get stuff done, have great energy, and thrive in a fast paced environment.
  • You are independent, and want to solve complicated problems on a daily basis. We don’t hand you a spec on your first day, we let you choose what you want to work on.
  • You are confident in your engineering abilities, and you aren’t afraid to break things. We have an amazing team that can fix things quickly, so let’s figure out how to push the limits.

Desired

  • You’re into Javascript MVC frameworks. If not Backbone, maybe Ember, Spine, or Knockout.
  • You are a seasoned developer tying front end technologies into the back end. Whether you are in a Java environment or PHP... we don’t care. You don’t have to be an expert at everything, we just want you to to be excited about taking your production experience and jumping into an emerging tech stack(新兴的技术堆栈).
  • You believe in the fundamentals.
  • You’re an active contributor to any open source projects.
  • You’ve had previous mobile development experience.
  • You stay updated on current technologies -- go to meet up groups, have a favorite blog, follow your favorite developer on Twitter, etc. Whatever works for you.

其他职位的一些Qualifications

  • Demonstrable experience building world-class, consumer web application interfaces (在构建世界一流的用户级Web应用程序接口方面具有丰富的经验)
  • Expert Javascript/HTML/CSS/Ajax coding skills(专家级的JS/HTML/CSS/AJAX编程技能)
  • Strong programming skills in Ruby, Java, Python, or PHP(具有较强的Ruby,Java,Python或PHP编程技能)
  • Disciplined approach to testing and quality assurance(纪律的方法来测试和质量保证)
  • Strong command of web standards, CSS-based design, cross-browser compatibility (在Web标准,基于CSS的设计,跨浏览器兼容方面具有较强执行力)
  • Good understanding of web technologies (HTTP, Apache) and familiarity with Unix/Linux (了解Web技术(HTTP,Apache),熟悉Unix/Linux)
  • Knowledgeable foundation in interaction design principles (精通交互设计原则的基础)
  • Great written communication and documentation abilities (极佳的书面沟通和编写文档能力)
[2013-05-09]

HTTP -- The Protocol Every Web Developer Must Know

原文 part1 主要描述Request和Response响应头的信息 原文 part2 文本主要注解原系列第二部分

HTTPS

HTTPS就是在原有的IP->TCP->HTTP之间,添加一层加密协议SSL或者TLS,变成IP->TCP->SSL/TLS->HTTP

保持连接

HTTP1.0中,单次传输完成只之后就会关闭连接,传输多个文件就需要多次建立连接,容易造成网络延迟。 HTTP1.1默认保持连接,客户端可以发送Connection: closed来告诉服务器不用保持该连接(可用telnet调试验证)

cache Control Heahers

Document Expiration

使用Cache-Control(HTTP/1.1)和Expires(HTTP/1.0)响应头,Expires设定过期的绝对日期,只有当服务器和客户 端时间完全相同才准确,并不实用。Cache-Control则通过max-age=<s>设定相对日期,指定多少秒之后过期。 Cache-Control的其他属性:

  • no-cache: 客户端可以缓存,但是每次都要进行revalidate,和HTTP/1.0中的Pragma: no-cache一样
  • no-store: 客户端不缓存
  • must-revalidate: 相比no-cache,当无法进行validate(比如连接不上服务器时),不准使用cache

Server Revalidation

当使用Document Expiration的文档过期之后,需要向服务器缺认是否文件有变动(Revalidation确保 了缓存的文件是最新的,结合Document Expiration避免每次都进行Revalidation) 使用If-Modified-Since请求响应头时,基于时间来进行判断,服务器返回Last-Modified, 使用If-None-Match请求响应头时,基于Entity-Tags(内容的一个hash),服务器返回带Etag的响应头

[2013-05-09]

IDEA创建File Watcher来自动编译CoffeeScript

创建File Watcher

官方文档 1. 从JetBrains plugin repository安装File Watcher插件,并重启 2. 找到设置中的File Watchers选项,添加相应的需求并指定程序 3. 勾选Immediate file synchronization,当文件发生变化时会自动编译,否则只有执行保存操作才会编译

注意:设置Output Path时,使用IDEA变量时注意,ProjectFileDir和ModuleFileDir是不一样的,根据 是Project还是Module来使用,不然不会生效(虽然在变量预览里面看是一样的)

项目实践

注意事项

  • File Watcher内的Output Paths设定并不好用,直接将输出目录通过调用程序的参数传入就好
  • 设定show cansole选项为Always,会显示调用程序的完整语句,便于调试
  • File Type选项确定监测文件类型
  • Scope确定监测范围
  • Working Directory选项确定语句执行的目录

实现coffee文件的监测

自动编译成JS和Source Map文件

由于CoffeeScript 1.6.1之后支持sourcemap,因此不再需要预设的CoffeeScript Source Map方案, 直接适用CoffeeScirpt方案就好,设定Scope为Coffee所在文件夹,传入参数为: --map --compile -o $ProjectFileDir$/assets/js/ $FileName$

自动拷贝开发目录下的.coffee文件到资源目录下

由于我并没有将开发目录开放到线上环境,要支持source map必须要同时将.coffee文件同时拷贝到输出 的js文件所在的目录。注意coffee -m -o参数连用时,会自动设定source map文件中的 "sourceRoot": "../../dev/coffee",属性,也就是用上面的参数编译时,指向的.coffee文件 是开发目录下面的原始文件)而dev目录在测试时是不开放的

要解决上面的文件,就需要换成:先在开发目录下面生成js和map文件,然后执行一个脚本,将coffee文件 拷贝,js和map文件移动到线上的/assets/js/目录下。(这里需要监听js与map文件的产生,只好使用 nodejs来实现了。)首先取消CoffeeScript监听输出目录的设定,即在当前文件下生成js和map文件。

  1. 添加自定义Watcher
  2. 监听.coffee文件(File Type设置为coffee)
  3. 执行文件为node
  4. 传入参数为genProductFiles.js
  5. 执行目录为$ProjectFileDir$/dev/tools

编写genProductFiles注意事项

  • 为了实现预期效果,必须使用coffee -cm .的形式,切换到.coffee所在目录再调用, 不要引入路径参数和输出目录参数-o,不然都会添加到map文件中去而无法实现效果
[2013-05-08]

Source Maps 101

原文链接

Source Maps:找出正式代码和开发代码之间的映射关系

什么是Source Maps?

在编译正式代码的时候,将开发代码所在的行号信息保存到source map中去,当在正式代码中查询时, 会返回其所在开发代码的真实位置信息。(需要浏览器支持)

如何使用Source Maps

  1. 在压缩代码的同时,产生Source Maps文件(例如test.js,会生成test.js.map),同时在压缩后 的代码中加入引用Source Maps的URL,如//@ sourceMappingURL=test.js.map
  2. 支持Source Maps的浏览器在Source面板会根据Source Maps文件自动引用原来的JS文件
  3. 使用的压缩代码出错会自动在原始代码的基础上报错
  4. 在引入的原始文件中设置的断点会生效(昨晚测试的时候会出问题,但是今天OK了)

CoffeeScript中使用Source Maps

注意:文中编译Coffeescript的时候,官方的coffeescript程序还不支持Source Map,因此使用 了重写Coffee编译器的第三方NPM(coffee-script-redux)来生成Source Map文件,但是文中又没有 用后者编译CoffeeScript生成JS,感觉不妥当。[连IDEA的帮助文档也是用coffee-script-redux]
注意:CoffeeScript 1.6.1之后就支持Source Map了,因此就没有必要适用这一 号称“更好的Coffee编译器”的coffee-script-redux项目来生成Source Map文件了,直接 coffee -cm source就OK了

Source Maps工作原理

参看阮一峰的博文

[2013-05-07]

JS字符串的replace()方法与Date对象

replace()

JS在进行字符串的替换操作时,调用replace(RegExp, arg2)其中的arg2既可以是字符串,也可以是 一个构造函数,这个函数在正则表达式每适配到一次时,会自动传入相应的参数并调用产生替换字符串。 fn(matcheStr, capture1, capture2, ..., offset, originStr),matchStr为适配正则表达式的字符串, capture为在字符串中使用正则表达式的(...)所捕获的$1, $2, ...,offset为str在原始字符串中 的偏移量,originStr为原始字符串。

创建指定日期的Date对象

new Date('2013-5-6')
new Date('2013, 5, 6')
new Date(2013, 4, 6)
//Mon May 06 2013 00:00:00 GMT+0800 (CST)
new Date('2013-05-06')    
new Date(Date.UTC(2013, 4, 6))
//Mon May 06 2013 08:00:00 GMT+0800 (CST)
  • 传入表示日期的字符串参数,如new Date('2013, 5, 6'),JS会自动调用Date.parse()方法, 将其转换为毫秒数生成2013年5月6日0时0分0秒的时间对象
  • 传入表示日期的数字参数,如new Date(2013, 4, 6),JS会使用Date.UTC()处理参数的方法来创建Date对象。 与上者的区别就是月份基于0,小时数基于0,因此这里用4不是用5!而其他分钟,秒等则以1为单位, 但是创建的日期是基于本地时间,而不是GMT时间。调用new Date(Date.UTC(2013, 4, 6))生成的是 GMT时间与第一个相同。如下所示。
[2013-05-06]


Google的Python编码规范

原文链接

语言规则

迭代对象的方法

for key in adict: ...
if key not in adict: ...
if obj in alist: ...
for line in afile: ...
for k, v in dict.iteritems(): .

异常

  • raise MyException('Error message')或者raise MyException来抛出异常
  • 模块和包要实现自己的异常(继承自Exception)class Error(Exception):,可以用pass传递给上级
  • 不要使用会捕获所有异常的except:语句,除非re-raising或者是代码的最外层(并打印错误信息) except会捕获所有异常,包括拼写错误,Ctrl+C终止,sys.exit()调用等等各种并不想要捕获的异常
  • 捕获异常时,用except Error as error,而不是except Error, error,后者难以理解
  • try/except语句尽量简短
  • 用finally执行不管是否出错都要执行的语句,比如关闭文件等清除操作

编码规则

命名规则

  • module_namepackage_namemethond_namefunction_nameglobal_var_name instance_var_namefunction_parameter_namelocal_var_name
  • ClassNameExceptionName
  • GLOBAL_CONSTONT_NAME
  • 不要使用-,单个字母变量,双下划线首尾的变量

换行

碰到较长字符串时,使用括号('hello''world!')

换行对齐,使用下面两种方式,换行缩进需要4个空格

# Aligned with opening delimiter
foo = long_function_name(var_one, var_two,
                         var_three, var_four)

# 4-space hanging indent; nothing on first line
foo = long_function_name(
    var_one, var_two, var_three,
    var_four)

不要使用\换行,URL和较长的import语句不要换行,允许超出

空行

顶层的定义之间空2行,内部的方法定义之间空1行

空格

  • 括号与元素间不要留空spam(ham[1], {eggs: 2}, [])
  • : ,前面不留空,不是在行尾则后面留1个空print x, y
  • 访问对象属性的[]与对象之间不留空dict['key'] = list[index]
  • 当以关键字参数的形式调用时,不要在=左右留空complex(real, imag=0.0)
  • 不添加多余的空格用于对齐,比如注释,dict的key和value

注释

  • 一个函数必须要有docstring,除非不是外部可见,很短或者很明显。docstring描述的是调用方法, 而不是该函数的实现方法。需要包含Args、Returns、Raises部分
  • class的docstring的Attributes属性需要列出其公有属性

字符串

  • 用%操作符格式化字符串,除非简单的连接两个字符串,x = '%s, %s!' % (foo, bar)
  • 在循环内部不要使用+,+=操作符来连接字符串,因为string格式是固定的,每次操作都会重新生成 会导致循环时间二次方倍增长,将临时字符串放入数组中,最后''.join(arr)一下

其他tips

  • 非直接运行py文件,比如modules,不要添加#!/usr/bin/python
  • 尽量少使用(),返回语句,if语句等不要用()包裹
  • 没有父类的class,那么object是其父类,class SampleClass(object):,会继承object具有的 基本方法:__new__,__init__,__getattribute__,__hash__,__repr__,__str__
  • 使用with语句来打开文件和socket,with open("hello.txt") as hellp_fp:
  • TODO后用()注明联系方式,如果是将来需要做的事情,注明时间或事件
  • 一行只import一个module,按照standard library -> third-party -> application-specific的顺序
  • 模块文件名都用小写
[2013-05-04]

No newline at end of file

今天用gitk查看提交的项目时,发现了所有文件后都有\No newline at end of file,让我想起了 之前用vim和eclips的时候碰到的问题:vim默认在文件最后自动添加换行符,而eclips默认不会自动 添加,导致出错,应该设置成自动加上换行符。于是在intellij里面勾选 ensure line feed at file end on save,需要注意的是,intellij不会自动将原先不带换行符 的文件自动加上换行符,只有新建的文件或者手动添加或末尾的换行符时,才会在保存时自动添加

[2013-05-03]

Linux运行信息保存与syslog

随着对Linux系统的深入使用,经常碰到一些操作出错的情况,Linux一般会将不同的错误信 息记录到/var/log/目录下面的不同文件中去,有必要对这些文档所记录的内容和负责信 息记录的syslog程序进行了解

日志文件种类

  • cron: 记录成crontab相关的信息
  • dmesg: 系统开机时产生的各种信息(fedora18下没有)
  • lastlog: 所有帐号最近登录系统时信息
  • maillog或mail\/*:sendMail与dovecot产生信息
  • messages:系统错误信息,重要信息记录处
  • secure: 需要输入密码程序产生信息,如su,sudo,ssh等
  • wtmp, faillog:登录系统者的账户信息,后者是错误登录时的信息
  • httpd\/*, news\/*, samba\/*: 不同网络服务记录的信息

产生方式

  1. 应用程序自己生成:apache等
  2. 统一的Linux信息记录服务--syslogd(需将信息传给该服务才能记录)
  3. 记录系统核心信息的服务--klogd
  4. logrotate自动化处理所有日志信息

syslog

syslog记录的日志格式

一般都会具有1.发生日期与时间,2.发生主机名称,3.启动此事件的服务(如samba,xinetd等) 或者是函数名(如libpam),4.实际日志内容

配置syslogd rsyslog.conf

/etc/rsyslog.conf是syslogd的配置文档,设定(1)什么服务的(可以man 3 syslog查看) (2)什么等级的信息(info,notice,warn,error,crit,alert,emerg\/panic) (3)被记录在那个文件。语法为:

server-name [.=!] message-level
mail.info /var/log/maillog_info #mail服务大于等于info级别的信息记录到/var/log/maillog_info文档中去

rsyslog与syslog的比较

在我的fedora中,并没有找到鸟哥文中说的syslog.conf文件,而是rsyslog.conf,原来 这些发行版(包括centos6.2)已经用rsyslog代替了系统自带的syslog。 选择rsyslog主要原因有:1.支持Mysql,PostgresSQL,Oracle等。2.支持多个rsyslog进程 监听不同端口。3.兼容syslog.conf配置文件。4.支持消息转发。5.配置文件可写简单逻辑。 6.有现成的前端Web展示程序参看该文

[2013-05-02]

Linux中的防火墙及iptables

买了linode的服务器半个多月了,开了各种服务,防火墙的规则也多多少少写了一些,但对 于iptables的原理和配置都是一知半解,通过鸟哥的私房菜来学习一下防火墙相关的配 置。

Linux系统上防火墙的类别

  1. Netfilter(封包过滤机制),比如iptables
  2. TCP Wrapper(通过程序名称来实现控制)
  3. Proxy

TCP Wrappers

分析用户端想要连接的服务名称和IP,判断是否放行。其实就是通过/etc/hosts.allow/etc/hosts.deny这两个文档实现。所能管理的服务包括 1.super deamon(xinetd)所管理的服务(chkconfig --list显示出的服务), 2.支持libwrap.so模块的服务。

iptables相关

iptabls至少有3个tables

  1. filter 进出本机的封包(预设table), INPUT接收,OUTPUT发送,FORWARD转发(与nat table相关)
  2. nat 管理防火墙内部其他电脑
  3. mangle 特殊的封包路由有关

查看当前iptables规则

  1. sudo iptables -L -n-n表示不将hostneme转换成ip地址,可以通过-t nat的方式来指定输出的tbale,默认是filter其输出格式如下,不是很详细,一些细节无法体现。

    target prot opt source destination 动作 协议 说明 来源ip 输出ip 说明文档

  2. sudo iptables-save显示的是配置文件中的信息,比较详细

ip设定规则

  • -s-d分别指定输入输出ip地址
  • ip/n换算:n表示多少位固定,一共是32, 24表示前24个都是1,最后8个为0,也就是255.255.255.0
  • ip/n前加上!表示取反,即不允许

iptables配置流程

  1. 清空所有配置:iptabls -Fiptables -Xiptables -Z三条指令一起执行
  2. 定义预设policy:iptables -P INPUT DROP,允许输出:iptables -P OUTPUT ACCEPT 生成诸如:INPUT DROP[0:0]:FORWARD ACCEPT[0:0]之类的policy
  3. 设定规则:详见下面规则
  4. 查看改动结果:iptables-save

iptables配置规则

  1. iptables [-AI 鏈名] [-io 网卡] [-p 协议] [-s ip/n] [-d ip/n] -j [ACCEPT|DROP|REJECT|LOG] 其中,A在最后插入,I在前面插入,-i输入介质(配合INPUT),-o输出介质(配合OUTPUT)。 LOG表示符合该规则的封包信息会写入/var/log/messages档案中
  2. 指定端口:在ip后面加上端口信息,如[-s] [--sport xxxx][-d] [--dport oooo] 因为仅有TCP和UDP封包具有端口,所以要同时设定好[-p udp][-p tcp]
  3. 例子:iptables -A INPUT -i eth0 -p tcp -s 192.168.1.0/24 --sport 1024:65534 --dport ssh -j DROP只要來自 192.168.1.0/24 的 1024:65535 埠口的封包,且想要連線到本機的 ssh port 就予以抵擋。

利用iptabls来实现NAT服务器

iptables 指令能夠修改 IP 封包的表頭資料,連目標或來源的 IP 位址都可以修改! 甚至連 TCP 封包表頭的 port number 也能修改。详情参考鸟哥文档

[2013-05-01]