【JavaScript高级程序设计】第20和21章(JSON、Ajax和Comet)
20. JSON
2006年,Douglas CrockFord, JSON(JavaScript Object Notation)js对象表示法
- JSON语法可以表示以下三种类型的值
- 简单值:字符串、数值、布尔值、null,但是不支持undefined
- 对象:无序键值对
- 数组:有序值列表
- JSON字符串全部用双引号!!!
- JSON对象属性名必须加引号!!!
- 解析
- 早期使用eval()
- ES5定义了全局对象JSON
stringify()
parse()
- 所有函数及原型成员都会被忽略,不体现在结果中
- 值为
undefined
的属性会被跳过
JSON.stringify(obj, filter, option)
toJSON
方法 —> 如果有该方法,JSON.stringify()
会执行该方法
var book = {
title: 'Professional JavaScript',
authors: ["Nicholas C. Zakas"],
edition: 3,
year: 2011
};
console.log(JSON.stringify(book));
console.log(JSON.stringify(book, ['title', 'authors']));
console.log(JSON.stringify(book, null, 4));
console.log(JSON.stringify(book, null, "----"));
21. Ajax和comet
Asynchronous JavaScript and XML
能够向服务器请求额外的数据,而无需卸载页面。
21.1 XMLHttpRequest
xhr.open('get', '/api', asyncBoolean)
;xhr.send(null);
- 响应
responseText
responseXML
status
statusText
XHR.readyState
- 所有可能取值:
- 0 未初始化
- 1 启动open
- 2 发送send
- 3 接收
- 4 完成
readystatechange
事件setRequestHeader()
getResponseHeader()
getAllResponseHeaders()
- 所有可能取值:
- HTTP头部信息
- 请求头部
Accept
Accept-Charset
Accept-Encoding
Accept-Language
Connection
Cookie
Host
发出请求的页面所在的域Referer
发出请求的页面的URIUser-Agent
浏览器的用户代理字符串
- 请求头部
- GET
- 查询字符串中每个参数的名称都必须使用
encodeURIComponet()
进行编码
- 查询字符串中每个参数的名称都必须使用
function addURLParam(url, name, value){
url += url.includes('?') ? '&' : '?';
url += encodeURIComponent(name) + '=' + encodeURIComponet(value);
return url;
}
- POST
- POST比GET更安全,因为参数不会被保存在浏览器历史或web服务器中。
application/x-www-form-urlencoded
21.2 XHR 2
- FormData
append()
- 超时设定
XHR.timeout = 1000
overrideMimeType()
21.3 进度事件Process Events
- 6个进度事件:(简化异步交互模型)
loadstart
/progress
/error
/abort
/load
/loadend
onprocess
:lengthComputable
/position
/totalSize
21.4 跨域资源共享CORS
默认情况下,XHR只能访问与包含它的页面位于同一个域内的资源
CORS定义了在必须访问跨域资源时,浏览器应该如何与服务器沟通。
CORS背后的基本思想,就是使用自定义的HTTP头部,让浏览器与服务器进行沟通,从而决定请求或响应是否成功。
- 同源策略:为通信设置“同域,同端口,同协议”的限制
- IE8引入了XDR(XDomainRequest)
- cookie不随请求发送,也不随响应返回
- 只能设置请求头部的Content-Type
- 不能访问响应头部信息
- 只支持GET和POST
- CSRF(cross-site Request Forgery)跨站请求伪造
- 未被授权的系统有权访问某个资源
- 解决方案:SSL连接、每次请求附带验证
- cookie信息验证不能防范CSRF攻击
- XSS(Cross-Site Scripting)跨站脚本攻击
- 为了不和CSS混淆
Access-Control-Allow-Origin
Preflighted Requests
透明服务器验证机制OPTIONS
方法请求头部Origin
Access-Control-Request-Method
Access-Control-Request-Headers
- 响应头部
Access-Control-Allow-Origin
Access-Control-Allow-Methods
Access-Control-Allow-Headers
Access-Control-Max-Age
- 带凭据的请求
- 默认情况下,跨源请求不提供凭据(Cookie、HTTP认证及客户端SSL证明)
- 通过设置
withCredentials
为true
,可以指定某个请求应该发送凭据 Access-Control-Allow-Credentials: true
- 其他跨域技术
- 图像Ping
一个网页可以从何网页中加载图像,不受跨域影响,这是在线广告跟踪浏览量的主要方式。
图像Ping只能用于浏览器对服务器的单向通信 - JSONP
- JSONP是JSON with padding,填充式JSON或参数式JSON
http://xxx.net/json/?callback=handleResponse
- 通过查询字符串指定JSONP服务的回调函数
<script>
和<img>
都有能力不受限制的跨域加载资源
function handleResponse(response){ console.log(response) } var script = document.createElement("script"); script.src = " http://219.216.80.193:3000/menus?callback=handleResponse"; document.body.insertBefore(script, document.body.firstChild);
- Comet服务器推送
- Ajax是一种从页面向服务器请求数据的技术;而comet是一种服务器向页面推送数据的技术
- 有两种实现Comet的方式:长轮询和流
- 长轮询是传统轮询(短轮询)的一个翻版。
- 短轮询即浏览器定时向服务器发送请求,看有没有更新的数据。
- 长轮询是页面发起一个请求到服务器,然后服务器一直保持连接打开,直到有数据可发送。
- 短轮询是服务器立即发送响应,无论数据是否有效。长轮询是一直等待一个有效响应。
- HTTP流,在页面的整个生命周期内只有一个HTTP连接
- 浏览器发送一个请求,服务器保持连接打开,然后周期性地向浏览器发送数据。
- SSE(server-sent events 服务器发送事件)只读Comet
- 到服务器的单向连接
text/event-stream
var src = new EventSource("myEvents.php");
- 到服务器的单向连接
- Web Sockets
- 目标是在一个单独的持久连接上提供全双工的双向通信
- URL模式:
ws://
- 使用自定义协议的好处是,能够在客户端和服务器之间发送非常少量的数量,而不用担心HTTP那样字节级的开销。
var socket = new WebSocket(url);
readyState
/close()
- 图像Ping