York's Blog

AJAX

如何发请求?

  • 用 form 可以发请求,但是会刷新页面或新开页面
  • 用 a 可以发 get 请求,但是也会刷新页面或新开页面
  • 用 img 可以发 get 请求,但是只能以图片的形式展示
  • 用 link 可以发 get 请求,但是只能以 CSS、favicon 的形式展示(必须appendChild在页面里面)
  • 用 script 可以发 get 请求,但是只能以脚本的形式运行(必须appendChild在页面里面)

微软的突破

IE 5 率先在 JS 中引入 ActiveX 对象(API),使得 JS 可以直接发起 HTTP 请求。
随后 Mozilla、 Safari、 Opera 也跟进(抄袭)了,取名 XMLHttpRequest,并被纳入 W3C 规范

AJAX(Async Javascript And XMLHTTPRequest)

Jesse James Garrett 将如下技术取名叫做 AJAX:异步的 JavaScript 和 XML

  1. 使用 XMLHttpRequest 发请求
  2. 服务器返回 XML 格式的字符串
  3. JS 解析 XML,并更新局部页面

AJAX的优点

  1. get、post、put、delete 请求都行
  2. 响应的第四部分是字符串,可以用 JSON 语法表示一个对象,也可以用 JSON 语法表示一个数组,还可以用 XML 语法,还可以用 HTML 语法,还可以用 CSS 语法,还可以用 JS 语法,还可以用我自创的语法

如何使用 XMLHttpRequest

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
28
29
myButton.addEventListener('click', (e)=>{
let request = new XMLHttpRequest()
request.open('get', '/xxx') // 配置request
request.send()
request.onreadystatechange = ()=>{
if(request.readyState === 4){
console.log('请求响应都完毕了')
console.log(request.status)
if(request.status >= 200 && request.status < 300){
console.log('说明请求成功')
console.log(typeof request.responseText)
console.log(request.responseText)
let string = request.responseText
// 把符合 JSON 语法的字符串
// 转换成 JS 对应的值
let object = window.JSON.parse(string)
// JSON.parse 是浏览器提供的
console.log(typeof object)
console.log(object)
console.log('object.note')
console.log(object.note)

}else if(request.status >= 400){
console.log('说明请求失败')
}

}
}
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 后端代码
}else if(path==='/xxx'){
response.statusCode = 200
response.setHeader('Content-Type', 'text/json;charset=utf-8')
response.setHeader('Access-Control-Allow-Origin', 'http://frank.com:8001')
response.write(`
{
"note":{
"to": "小谷",
"from": "方方",
"heading": "打招呼",
"content": "hi"
}
}
`)
response.end()

readyState是一个只读属性,用一个整数和对应的常量,表示XMLHttpRequest请求当前所处的状态。

  • 0:对应常量UNSENT,表示XMLHttpRequest实例已经生成,但是open()方法还没有被调用。
  • 1:对应常量OPENED,表示send()方法还没有被调用,仍然可以使用setRequestHeader(),设定HTTP请求的头信息。
  • 2:对应常量HEADERS_RECEIVED,表示send()方法已经执行,并且头信息和状态码已经收到。
  • 3:对应常量LOADING,表示正在接收服务器传来的body部分的数据,如果responseType属性是text或者空字符串,responseText就会包含已经收到的部分信息。*
  • 4:对应常量DONE,表示服务器数据已经完全接收,或者本次接收已经失败了。

JSON

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式
JSON与JavaScript的区别

  1. JS 是一门语言,JSON 是另一门语言,JSON 这门语言抄袭了 JS这门语言
  2. JSON与javascript没有抄袭function,undefined和变量
  3. JSON的字符串首尾必须用””

JSON与JavaScript的区别

服务器第四部分永远都是返回字符串,只是字符串刚好符合JSON对象的语法
window.JSON.parse() 是浏览器提供的API,把符合JSON语法的字符串转换成JS对应的值

同源策略

只有 协议+端口+域名 一模一样才允许发 AJAX 请求

为什么form表单提交没有跨域问题,但ajax提交有跨域问题?
因为原页面用 form 提交到另一个域名之后,原页面的脚本无法获取新页面中的内容。所以浏览器认为这是安全的。
而 AJAX 是可以读取响应内容的,因此浏览器不能允许你这样做。
如果你细心的话你会发现,其实请求已经发送出去了,你只是拿不到响应而已。
所以浏览器这个策略的本质是,一个域名的 JS ,在未经允许的情况下,不得读取另一个域名的内容。但浏览器并不阻止你向另一个域名发送请求。

浏览器必须保证

  1. 只有 协议+端口+域名 一模一样才允许发 AJAX 请求
  2. CORS 可以告诉浏览器,我俩一家的,别阻止他

CORS(Cross-Origin Resource Sharing)跨(站/源)资源共享

突破同源策略 === 跨域
respon.setHeader(‘Access-Control-Allow-Origin’,’http://frank.com:8001') 在后端服务器添加CORS,可以让不同源的访问

chrome认为GET请求理论上不会有request.body,所有它不展示

AJAX 的所有功能

  • 客户端的JS发起请求(浏览器上的)
  • 服务端的JS发送响应(Node.js上的)
  1. JS 可以设置任意HTTP请求 header 吗
    第一部分 request.open(‘get’, ‘/xxx’)
    第二部分 request.setHeader(‘content-type’,’x-www-form-urlencoded’)
    第四部分 request.send(‘a=1&b=2’)
  2. JS 可以获取任意HTTP响应 header 吗?
    第一部分 request.status / request.statusText
    第二部分 request.getResponseHeader() / request.getAllResponseHeaders()
    第四部分 request.responseText

写 window.jQuery.ajax

封装AJAX函数

AJAX接受两种参数

AJAX接受两种参数

ES6析构赋值

ES6析构赋值

回调是啥

call a function
call a function back
callback

回调的问题

问题是每个程序员的回调名不一样

Promise 解决了这个问题

1
2
3
4
5
6
7
8
9
10
11
12
13
function xxx(){
return new Promise((f1, f2) => {
doSomething()
setTimeout(()=>{
// 成功就调用 f1,失败就调用 f2
},3000)
})
}

xxx().then(success, fail)

// 链式操作
xxx().then(success, fail).then(success, fail)

return new Promise(function(resolve,reject){}) 如果成功就调用resolve,如果失败就调用reject

结构化编程

  1. 顺序执行
  2. if…else…
  3. while/for循环

TCP/IP
HTML/CSS/JS/JSON 是基于HTTP传输的,HTTP是基于TCP/IP传输的
TCP建立连接要确定四个条件

  1. 浏览器可以发请求
  2. 浏览器可以收请求
  3. 服务器可以发请求
  4. 服务器可以收请求
    客户端与服务器

console.time(); console.timeend()中间放入代码,可以得到代码运行的时间
因为jQuery发现你的返回值的content-type是text/json,他就会自动把字符串转成对象(window.JSON.parse)

Proudly published with Hexo