基础
html书写规范
为每个HTML页面的第一行添加标准模式(standard mode)的声明,确保在每个浏览器中拥有一致的展现。
<!DOCTYPE html>
文档类型声明统一为HTML5声明类型,编码统一为UTF-8。
<meta charset="UTF-8"> <HEAD>中添加信息。 <meta name="author" content="xxx@xxx.xxx">//作者 <meta name="description" content="hello">//网页描述 <meta name="keywords" content="a,b,c">//关键字,“,”分隔 <meta http-equiv="expires" content="Wed, 26 Feb 1997 08:21:57GMT">//设定网页的到期时间。一旦网页过期,必须到服务器上重新调阅 <meta http-equiv="Pragma" content="no-cache">//禁止浏览器从本地机的缓存中调阅页面内容 <meta http-equiv="Window-target" content="_top">//用来防止别人在框架里调用你的页面 <meta name="robots" content="none">//content的参数有all,none,index,noindex,follow,nofollow,默认是all <link rel="Shortcut Icon" href="favicon.ico">//收藏图标 <meta http-equiv="Cache-Control" content="no-cache, must-revalidate">//网页不会被缓存IE支持通过特定 //<meta>标签来确定绘制当前页面所应该采用的IE版本。除非有强烈的特殊需求,否则最好是设置为edge mode ,从而通知IE采用其所支持的最新的模式。 <meta http-equiv="X-UA-Compatible" content="IE=Edge">
非特殊情况下CSS样式文件外链至HEAD之间
JAVASCRIPT文件外链至页面底部。
<!DOCTYPE html> <html> <head> <link rel="stylesheet" href="css/main.css"> </head> <body> <!-- 逻辑代码 --> <!-- 逻辑代码底部 --> <script src="lib/jquery/jquery-2.1.1.min.js"></script> </body> </html>
引入JAVASCRIPT库文件,文件名须包含库名称及版本号及是否为压缩版。
jQuery-1.8.3.min.js
引入JAVASCRIPT插件, 文件名格式为库名称+.+插件名称。
jQuery.cookie.js
HTML属性应当按照以下给出的顺序依次排列,来确保代码的易读性。
class id 、 name data-* src、for、 type、 href title、alt aria-*、 role
编码均遵循XHTML标准, 标签、属性、属性命名由小写英文、数字和_组成,且所有标签必须闭合,属性值必须用双引号””,
避免使用中文拼音尽量简易并要求语义化。
CLASS --> nHeadTitle --> CLASS遵循小驼峰命名法(little camel-case) ID --> n_head_title --> ID遵循名称+_ NAME --> N_Head_Title --> NAME属性命名遵循首个字母大写+_ <div class="nHeadTitle" id="n_head_title" name="N_Head_Title"></div>
当JAVASCRIPT获取单个元素时,通常使用document.getElementById来获取dom元素,document.getElementById兼容所有浏览器,但IE浏览器会混淆元素的ID和NAME属性,所以要区分ID和NAME命名。
<input type="text" name="test"> <div id="test"></div> <button onclick="alert(document.getElementById('test').tagName)"></button> <!-- ie6下为INPUT -->
特殊符号应使用转意符。
< --> < > --> > 空格 -->
含有描述性表单元素(INPUT,TEXTAREA)添加LABEL。
<p> <label for="test">测试</label> <input type="text" id="test" /> </p>
多用无兼容性问题的HTML内置标签,比如SPAN、EM、STRONG、OPTGROUP、LABEL等,需要自定义HTML标签属性时,首先考虑是否存在已有的合适标签可替换,如果没有,可使用须以“data-”为前缀来添加自定义属性,避免使用其他命名方式。
语义化HTML。
尽可能减少
嵌套。书写链接地址时避免重定向。
href=”http://www.toutiao.com/“ //即在URL地址后面加“/”
HTML中对于属性的定义,确保全部使用双引号,绝不要使用单引号
Web Api
API 设计方案
- Http的请求分为URL约定规则、请求参数规则
URL规则: http://{server}/{product}/{version}/{logic}/{method}?{query_string}
server: 为具体的服务域名
product: 为应用工程名
version: 为具体版本号, 便于将来的功能扩展, 可以暂定为 v1, v2
logic: 为具体业务逻辑的初步划分, 比如后端管理方法, app端的请求方法
method: 具体业务的方法
把 method 和 version 放到在URI中
这样可以使API 版本化,方便版本控制,同时也便于日后API的分流
Http的响应规则
HTTP响应码为200, 返回结果为JSON字符串的形式:
如果响应结果正确,则返回结果如下所示:
1 | { |
如果响应结果失败,则返回如下结果:
1 | { |
Auth 权限验证
API 的权限验证,有很多方案,目前成熟的OAuth 2.0框架等,不过 ,最简单的还是利用 Http Header 来完成这一目标。 将token 通过 Header 传递。来实现权限验证。
API 在设计的时候,最好不要将业务错误码与HTTP状态码的绑定,重新定义一套业务错误码,来区分HTTP 的状态码。
状态码的定义也最好有一套规范,类似于HTTP 的状态码,可以按照用户相关、授权相关、各种业务,做简单的分类。
// Code 业务自定义状态码定义示例
// 授权相关
1001: 无权限访问
1002: access_token过期
1003: unique_token无效
…
// 用户相关
2001: 未登录
2002: 用户信息错误
2003: 用户不存在
// 业务相关
3001: 业务XXX
3002: 业务XXX
// 系统异常
5001:Internal Server Error
其他一些建议
规范统一的命名
使用驼峰式或者下划线格式都可以,统一规范就行。不过,目前基本都是统一小写加下划线比较好。如:user_id,user_name,user_age等。
语义清晰,遵守常用缩写
字段的名字最好能体现字段的类型,遵守一些常用的缩写,如:user_name, task_desc, date_str 等空值、空字段的处理
空值、空字段的处理也是比较容易出问题。统一空值用null 。除了布尔类型的,其余的空值统一用null表示,客户端保证每种字段的null可以被正常处理。各个Action 尽量符合CRUD操作的原则。
给不同类型设置默认空值
除了null,尽量对字段设置“默认值”,如数字就是0 bool 类型的值,统一成数字0和1 字符串就是空字符串"" 数组就是空数组[] 对象就是空对象{} 时间日期类型强制只能传标准GMT/UTC时间戳 这样可以避免客户端处理空值产生的异常。
完整的URL
API里面的数据也会有URL类型的,一般来说如用户的头像、各种图片、音频等资源,都是以URL链接的形式返回的。
返回的URL一定要“完整”,主要指的是不要忘记URL里面的协议部分。应该是http://www.abc.com/1.jpg。REST 安全
可以使用固有的 HTTP 基本验证,你还可以考虑通过支持表单验证,LTPA 验证,Open ID 验证等方式,来满足更多的企业安全要求。尽量将API部署在专用域名之下。例如:https://api.example.com。
API返回的数据格式,应该尽量使用JSON,避免使用XML。
返回正确 HTTP 响应代码,同时重新定义一套业务错误码,来区分HTTP 的状态码。
完善的文档,最好能自动生成在线API文档,这样文档能随时保持最新。
例如:SwaggerUI。
接口安全和参数校验
- 一般通用的做法,是采用几步来保证接口和数据安全:
首先一个是基于CA证书的HTTPS进行数据传输,防止数据被窃听;
然后是采用参数加密签名方式传递,对传递的参数,增加一个加密签名,在服务器端验证签名内容,防止被篡改;
最后是对一般的接口访问,都需要使用用户身份的token进行校验,只要检查通过才允许访问数据。
- 接口的访问方式,大概可以分为几类:
使用用户名密码。
这种方式比较简单,可以有效识别用户的身份(如包括用户信息、密码、或者相关的接口权限等等)。验证成功后,返回相关的数据。
使用安全签名
这种方式提交的数据,URL连接的签名参数是经过安全一定规则的加密的,服务器收到数据后也经过同样规则的安全加密,确认数据没有被中途篡改后,再进行数据修改处理。因此我们可以为不同客户端,如Web/APP/Winfrom等不同接入方式指定不同的加密秘钥,但是秘钥是双方约定的,并不在网络连接上传输,连接传输的一般是这个接入的AppID,服务器通过这个AppID来进行签名参数的加密对比。目前微信后台的回调处理机制,应该就是这么处理的。
公开的接口调用
不需要传入用户令牌、或者对参数进行加密签名的,这种接口一般较少,只是提供一些很常规的数据显示而已。
Jade
Jade 是一个高性能的模板引擎,它深受 Haml 影响,它是用 JavaScript 实现的,并且可以供 Node 使用。
使用
https://segmentfault.com/a/1190000000357534#articleHeader6
Jade代码
doctype html
html
head
title my jade template
body
h1 Hello
翻译成html为
<!DOCTYPE html>
<html>
<head>
<title>my jade template</title>
</head>
<body>
<h1>Hello</h1>
</body>
</html>
例子
#content
.block
input#bar.foo1.foo2
ul#books
li: a(href="#book-a") Book A
p
| foo bar
| hello world
翻译成html
<div id="content">
<div class="block">
<input id="bar" class="foo1 foo2"/>
</div>
</div>
<ul id="books">
<li><a href="#book-a">Book A</a></li>
</ul>
<p>
foo bar
hello world
</p>
实战
引用js时如何防止缓存
在js脚本中动态创建脚本
在引用的网站中引入如下js:
<script type="text/javascript" > loadJs("http://localhost:8081/static/html/convention.js.js?timestamp="+Math.random(),null); </script>
http://localhost:8081/static/html/convention.js.js 内容如下:
loadJs("/static/js/convention.js?aaa=222", null);
loadJs 就是创建JavaScript节点,实现如下:
function loadJs(url, callback) { var done = false; var script = document.createElement('script'); script.type = 'text/javascript';//do not 'application/javascript',because Low version of the browser is not compatible script.language = 'javascript'; script.charset = "utf-8"; script.src = url; //script.setAttribute('src', url); script.onload = script.onreadystatechange = function () { if (!done && (!script.readyState || script.readyState == 'loaded' || script.readyState == 'complete')) { done = true; script.onload = script.onreadystatechange = null; if (callback) { console.log('load ' + url + ' success.'); callback.call(script); } } }; document.getElementsByTagName("head")[0].appendChild(script); };
以后修改bug时,只需要修改WEB-INF/static/html/convention.js.js中的版本号即可