JS红宝书-第二十四章-网络请求与远程资源

本章总结了JS中远程请求和跨域的方法

1.XMLHttpRequest

XHR对象由微软发明,用于实现Ajax(Asynchronous JS+XML),使服务器请求不需要刷新页面
本章中介绍的方法从XMLHttpRequest->Fetch API进行介绍

1.1 使用步骤

1.1.1 构造XMR对象

注意,监听器的设置可以在创建对象之后,open操作之前进行

1.1.2 打开连接

1.1.3 发送

1
2
3
4
5
6
7
8
9
let xhr = new XMLHttpRequest()
xhr.onerror = function (ev) {
console.log(ev)
}
xhr.open("get","https://www.baidu.com",false)
xhr.send(null)
if(xhr.status >= 200 && xhr.status < 300) console.log(xhr.responseText)
else console.log(xhr.readyState)
xhr.status

1.2 XHR状态机

readyState:

  • 0:未初始化
  • 1:已打开
  • 2:已发送
  • 3:接受中
  • 4:完成

1.3 HTTP头部

1.3.1 设置HTTP头部

注意,设置请求头部可以在open操作之后,send操作之前进行
默认包含了

  • Accept
  • Accept-Charset
  • Accept-Encoding
  • Language
  • Connection
  • Cookie
  • Host
  • Referer
  • User-Agent
1
2
3
4
5
let xhr = new XMLHttpRequest()
xhr.open("get","https://www.baidu.com",false)
xhr.setRequestHeader("test", "test")
xhr.send(null)
xhr.getAllResponseHeaders()

1.4 请求参数

1.4.1 GET参数

可以使用encodeURIComponent对URL进行查询

1
2
3
4
5
6
7
8
url = "https://www.baidu.com/"
const add = (key, value) => {
url += url.indexOf("?")===-1?'?':'&'
url += `${encodeURIComponent(key)}=${encodeURIComponent(value)}`
}
add('test','111')
add('test1','222')
console.log(url)

1.4.2 POST参数

可以使用XHR模拟表单提交,但是要先设置头部格式 Content-Type
常用的有四种Content-Type:

  • application/x-www-form-urlencoded 表单
  • application/json JSON格式
  • multipart/form-data 文件
  • text/xml XML格式
1
2
3
4
5
6
let xhr = new XMLHttpRequest()
xhr.open("post","https://www.baidu.com/",false)
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded")
let form = new FormData()
form.append("test","test")
xhr.send(form)

1.5 进度事件

  • loadstart 接受第一个字节触发
  • progress 接受响应期间反复触发
  • error 出现问题触发
  • abort 被打断触发
  • load 接受完成时响应
  • loadend 在完全结束时,即error、abort、load结束
1
2
3
4
5
6
7
8
9
10
let xhr = new XMLHttpRequest()
xhr.onreadystatechange = function (ev) {
console.log(ev)
console.log(this.readyState)
}
xhr.open("post","https://www.baidu.com/",false)
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded")
let form = new FormData()
form.append("test","test")
xhr.send(form)

2.跨域资源共享

为了防止恶意请求行为,默认情况下,XHR只能访问同一域名内资源
CORS定义了如何实现跨域通信
首先浏览器发出的请求中都有Origin头,例如:Origin: https://baidu.com
然后返回Access-Control-Allow-Origin: https://.... or *
默认而言,跨域请求:

  • 只支持GET或POST请求
  • 不可以发送/接受Cookie
  • 不能自定义头部
  • 返回头部中返回空字符串

2.1 预检请求

虽然默认而言不可以出现自定义头部的情况,但是如果处理包含以上四种情况的高级请求时,会向服务器发送一个OPTION类型的请求,包含以下头部

  • Origin
  • Access-Control-Request-Headers
  • Access-Control-Request-Method
    服务器应当返回的头包括
  • Access-Control-Allow-Origin
  • Access-Control-Allow-Methods
  • Access-Control-Allow-Header
  • Access-Control-Max-Age
  • Access-Control-Allow-Credentials 是否允许带凭据的请求

2.2 替代性跨源技术

2.2.1 图片探测

使用IMG标签进行快速响应,但是无法通过查询获得具体内容

2.2.2 JSONP

JSONP的形式
http://test.cc/json?callback=handle
只需要在本地声明

1
2
3
function handle(val) {
console.log(val)
}

然后在需要加载的时候,新建一个页面元素

1
2
3
let sc = document.createElement("scirpt")
sc.src = "...."
document.body.insertBefore(sc, document.body.firstChild)

缺点:

  • 无法避免恶意内容
  • 难以确定是否失败

面试题

1.网络协议方面

1.1 HTTP原理

1.2 HTTPs原理

1.3 HTTP不同版本号

1.4 WS原理

1.10 OSI七层模型

1.11 TCP/UDP区别

1.12 TCP系列问题

TCP为什么可靠
TCP握手,为什么如此握手
TCP滑动窗口

1.13 UDP系列问题

如何实现有序传输?

2.应用层面方面

2.1 CDN原理

2.2 POST与GET的区别

2.3 HTTP缓存机制

  1. 强缓存和内容协商的本质区别
  2. 还有别的缓存方案吗,临时存一些数据用什么(答cookie或localStorage)
  3. 问了下 etag 优点,从 last-modified 缺点来讲

2.4 HTTP常用头(KEEP-ALIVE?)

2.5 跨标签页通讯

2.6 Fetch API与传统 XHR 的区别

3.安全方面

3.1 JWT

3.2 XSS

1
1. POST要比GET占有更多的资源,因此性能方面可以从这里下手
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function add(x,y){
return x+y
}
add.call = function(){
Object.defineProperty(this, "args", {
writable: true,
value: this.arguments,
})
console.log(this.args)
add.__proto__.call(this, this.arguments)
}
add(1,2)//3

add(1,2,3)//3

add(1,2,3,4)

JS红宝书-第二十四章-网络请求与远程资源
https://tech.jasonczc.cn/2022/language/javascript/redbook/24-network-requests-and-remote-resources/
作者
CZY
发布于
2022年5月2日
许可协议