内容简介:浏览器与服务器之间,采用 HTTP 协议通信。用户在浏览器地址栏键入一个网址,或者通过网页表单向服务器提交内容,这时浏览器就会向服务器发出 HTTP 请求。2005年2月,AJAX 这个词第一次正式提出,它是 Asynchronous JavaScript and XML 的缩写,指的是通过 JavaScript 的异步通信,从服务器获取 XML 文档从中提取数据,再更新当前网页的对应部分,而不用刷新整个网页。 后来,AJAX 这个词就成为 JavaScript 脚本发起 HTTP 通信的代名词,也就是说,
浏览器与服务器之间,采用 HTTP 协议通信。用户在浏览器地址栏键入一个网址,或者通过网页表单向服务器提交内容,这时浏览器就会向服务器发出 HTTP 请求。
2005年2月,AJAX 这个词第一次正式提出,它是 Asynchronous JavaScript and XML 的缩写,指的是通过 JavaScript 的异步通信,从服务器获取 XML 文档从中提取数据,再更新当前网页的对应部分,而不用刷新整个网页。 后来,AJAX 这个词就成为 JavaScript 脚本发起 HTTP 通信的代名词,也就是说,只要用脚本发起通信,就可以叫做 AJAX 通信。
具体来说,AJAX 包括以下几个步骤。
- 创建 XMLHttpRequest 实例
- 发出 HTTP 请求
- 接收服务器传回的数据
- 更新网页数据
概括起来,就是一句话,AJAX 通过原生的 XMLHttpRequest
对象发出 HTTP 请求,得到服务器返回的数据后,再进行处理。
一旦拿到服务器返回的数据,AJAX 不会刷新整个网页,而是只更新网页里面的相关部分,从而不打断用户正在做的事情。
注意,AJAX 只能向同源网址(协议、域名、端口都相同)发出 HTTP 请求,如果发出跨域请求,就会报错。
2. 如何发请求?(背景)
用 form
可以发请求,但是会刷新页面或新开页面
用 a
可以发 get
请求,但是也会刷新页面或新开页面
用 img
可以发 get
请求,但是只能以图片的形式展示
用 link
可以发 get
请求,但是只能以 CSS、favicon 的形式展示
用 script
可以发 get
请求,但是只能以脚本的形式运行
提出需求:如何不受限制的发请求?
-
get
post
delete
请求都行 - 想以什么形式展示就以什么形式展示
3. 微软的突破
IE 5 率先在 JS 中引入 ActiveX 对象(API),使得 JS 可以直接发起 HTTP 请求。
随后 Mozilla、 Safari、 Opera 也跟进(抄袭)了,取名 XMLHttpRequest
,并被纳入 W3C 规范。
可这样使用XMLHttpRequest: var x = new XMLHttpRequest() 复制代码
注意:XMLHttpRequest 是 window下的全局对象
4. AJAX(异步的 JavaScript 和 XML)
Jesse James Garrett 将如下技术点的方案取名叫做 AJAX:异步的 JavaScript 和 XML
- 使用 XMLHttpRequest 发请求
- 服务器返回 XML 格式的字符串(如今用JSON代替了XML)
- JS 解析 XML,并更新局部页面
5. 如何使用 XMLHttpRequest
5.1 XMLHttpRequest对象用法例子
客户端代码:
let request = new XMLHttpRequest(); //创建一个XMLHttpRequest request.onreadystatechange = function(){ // 通信成功时,状态值为4 if (request.readyState === 4){ if (request.status === 200){ console.log(request.responseText); } else { console.error(request.statusText); } } }; request.onerror = function (e) { console.error(request.statusText); }; request.open('GET', '/endpoint', true); //配置 request.send(null); //发送 复制代码
服务器端代码:
if(path === '/'){ response.statusCode = 200 let string = fs.readFileSync('./index.html') response.setHeader('Content-Type', 'text/html;charset=utf-8') response.write(string) response.end() } 复制代码
-
http
请求的路径都是绝对路径.所以都是以/
开头 -
设置响应头中的
Content-Type,response.setHeader('Content-Type', 'text/html;charset=utf-8')
,即要求浏览器以HTML的语法解析这段字符串! -
对于HTTP来说,响应的第四部分始终都是字符串,因为
response.write(string)
返回的是字符串,我们给浏览器返回了符合html
格式的字符串。
5.2 XMLHttpRequest 的实例属性
-
XMLHttpRequest.readyState
XMLHttpRequest.readyState
返回一个整数,表示实例对象的当前状态。该属性只读。4
,表示服务器返回的数据已经完全接收,或者本次接收已经失败。 通信过程中,每当实例对象发生状态变化,它的readyState
属性的值就会改变。
var xhr = new XMLHttpRequest(); if (xhr.readyState === 4) { // 请求结束,处理服务器返回的数据 } else { // 显示提示“加载中……” } 复制代码
上面代码中, xhr.readyState
等于 4
时,表明脚本发出的 HTTP 请求已经完成。其他情况,都表示 HTTP 请求还在进行中。
-
XMLHttpRequest.onreadystatechange
实例的
readyState
属性变化,就会执行这个属性。 -
XMLHttpRequest.responseText
XMLHttpRequest.responseText
属性返回从服务器接收到的字符串,该属性为只读。 -
XMLHttpRequest.status
XMLHttpRequest.status
属性返回一个整数,表示服务器回应的 HTTP 状态码。 基本上,只有2xx和304的状态码,表示服务器返回是正常状态。
if (xhr.readyState === 4) { if ( (xhr.status >= 200 && xhr.status < 300) || (xhr.status === 304) ) { // 处理服务器的返回数据 } else { // 出错 } } 复制代码
6. 使用JSON解析响应的第四部分
XML语言结构的数据不好用且已经过时了,现使用JSON替代XML。 JSON是一门数据格式化语言,用来表示数据。 JSON官网:JSON
6.1 语法快速过
-
JS的数据类型仅剩
symbol
、undefined
、function
没抄 - 铁轨图(从左往右看)
JS VS JSON undefined 没有 null null 'janice' "janice" ['a','b'] ["a","b"] {name: 'janice'} {"name":"janice"} function fn(){} 没有 var a = {} 搞不定(没有变量) a.self = a 搞不定(没有变量) {__proto__} 没有原型链 复制代码
区别:
-
JSON没有抄袭
function
和undefined
-
JSON的字符串
string
首尾必须是 双引号"
6.2 如何使用JSON
if (path === '/xxx') { response.statusCode = 200 response.setHeader('Content-Type', 'text/json;charset=utf-8') response.write(` { "note":{ "to": "Rose", "from": "Jack", "heading": "经典片段", "content": "You jump,I jump." } } `) response.end() } 复制代码
服务器返回的是字符串,恰巧这个字符串刚好符合JSON对象的语法格式。
前端收到响应后:
if(request.status >= 200 && request.status < 300){ console.log('说明请求成功') let string = request.responseText // 把符合 JSON 语法的字符串转换成 JS 对应的值 let object = window.JSON.parse(string) // JSON.parse 是浏览器提供的 }else if(request.status >= 400){ console.log('说明请求失败') } 复制代码
7. 同源策略
只有 协议+端口+域名 一模一样才允许发 AJAX 请求
- baidu.com 可以向 www.baidu.com 发 AJAX 请求吗 no
- baidu.com:80 可以向 baidu.com:81 发 AJAX 请求吗 no
浏览器必须保证: 只有 协议+端口+域名 一模一样才允许发 AJAX 请求 CORS 可以告诉浏览器,我俩一家的,别阻止他
8. CORS 跨域
CORS(Cross-origin resource sharing),全称是“跨域资源共享”,是一个 W3C 标准。它允许浏览器向跨域的服务器,发出 XMLHttpRequest
请求,从而克服了 AJAX 只能同源使用的限制。
在代码中添加CORS头即可跨域:
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": "Rose", "from": "Jack", "heading": "经典片段", "content": "You jump,I jump." } } `) response.end() } 复制代码
注意:JSONP不能发起POST请求,要POST只能用CORS
彩蛋
面试问题:请使用原生JS发送Ajax请求
mybutton.addEventListener('click', (e) => { let request = new XMLHttpRequest() request.open('get', 'http://jack.com:8002/xxx') //配置request 参数分别为方法和路径 request.send() request.onreadystatechange = () => { if (request.readyState === 4) { if (request.status >= 200 && request.status < 300) { // 把符合 JSON 语法的字符串转换成 JS 对应的值 let string = request.responseText // JSON.parse 是浏览器提供的 let object = window.JSON.parse(string) console.log(object.note) } else if (request.status >= 400) { console.log('请求失败') } } } }) 复制代码
参考链接
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。