目录
一、AJAX 的含义,作用,原理
AJAX 的含义,作用
AJAX,“Asynchronous JavaScript and XML”(异步的 JavaScript 和 XML)是一种用于创建快速动态网页的技术。 它允许网页的某一部分与服务器进行通信,获取或发送数据,然后只更新这部分内容,而不需要重新加载整个页面。这样,网页看起来就像是在“实时”地更新内容。
常用场景:表单验证是否登入成功、百度搜索下拉框提示、快递单号查询。
补充:XML是扩展标记语言,能够用一系列简单的标记描述数据。
AJAX 原理
AJAX 的原理是基于浏览器与服务器之间的异步通信。通过在用户和服务器之间加了一个中间层(AJAX引擎),使用户操作与服务器响应异步化。并不是所有的用户请求都提交给服务器,像一些数据验证和数据处理等都交给 AJAX 引擎自己来做,只有确定需要从服务器读取新数据时再由 AJAX 引擎代为向服务器提交请求。这意味着在请求数据的过程中,用户仍然可以与页面进行交互,而不会受到页面刷新的影响。
通过 XMLHttpRequest 对象来向服务器发送异步请求,从服务器获得数据,然后用 JavaScript 来操作 DOM 而更新页面。这其中最关键的是从服务器获得请求数据。要清楚这个过程和原理,我们必须对 XMLHttpRequest有所了解 。
XMLHttpRequest 是一个浏览器提供的 JavaScript 对象,用于在客户端与服务器之间建立异步通信,实现网页的局部数据更新而无需重新加载整个页面。
AJAX的工作原理(使用 XMLHttpRequest 对象)涉及以下几个关键步骤:
- 创建 XMLHttpRequest 对象: JavaScript 使用浏览器内置的 XMLHttpRequest 对象来向服务器发送 HTTP 请求。这个对象提供了与服务器通信的能力。
- 设置请求参数:通过 XMLHttpRequest 对象的 open() 方法,设置请求的类型(GET、POST等)、请求的 URL 以及是否异步处理请求。
- 发送请求:调用 XMLHttpRequest 对象的 send() 方法,将请求发送给服务器。如果是 POST 请求,还需要在 send() 方法中传递请求体数据。
- 监听状态变化:通过给 XMLHttpRequest 对象的 onreadystatechange 事件绑定处理函数,可以监听请求的状态变化。当 readyState 属性变化时,处理函数会被触发。
- 处理服务器响应:当请求完成且状态码为 200 时,可以通过 XMLHttpReques t对象的 responseText 或 responseXML 属性获取服务器返回的响应数据。然后,可以使用 JavaScript 来操作 DOM ,更新页面的部分内容,从而实现无刷新更新页面的效果。
AJAX技术体系的组成部分
HTML,CSS,JavaScript,Dom,XML,XMLHttpRequest。
二、AJAX优缺点
优点
- 通过异步模式,提升了用户体验。
- 优化了浏览器和服务器之间的传输,减少不必要的数据往返,减少了带宽占用。
- AJAX 引擎在客户端运行,承担了一部分本来由服务器承担的工作,从而减少了大用户量下的服务器负载。
缺点
- 不支持浏览器 back 按钮。
- 安全问题:暴露了与服务器交互的细节。
- 对搜索引擎的支持比较弱。
- 破坏了程序的异常机制。
- 不容易调试。
最大的特点
实现动态不刷新(局部刷新),就是能在不更新整个页面的前提下维护数据。
三、原生JS AJAX请求步骤
//创建 XMLHttpRequest 对象
var xhr = new XMLHttpRequest();
//发送信息至服务器时内容编码类型
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
//接受服务器响应数据
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && (xhr.status == 200 || xhr.status == 304)) {
}
};
//规定请求的类型,URL,以及是否异步处理请求
xhr.open('GET',url,true);
//发送请求
xhr.send(null);
四、XMLHttpRequest 对象的常用方法和属性
XMLHttpRequest 对象在 JavaScript 中用于执行 HTTP 请求,以下是常用的方法和属性:
方法
- setRequestHeader(header, value): 设置请求的 HTTP 头。必须在 open() 和 send() 之前调用。
- open(method, url, async, user, password):初始化一个请求。
参数包括请求类型(GET、POST等),请求的 URL ,是否异步处理(默认为 true ),以及可选的用户名和密码。
- send(data):发送请求。
如果请求是 GET 类型,可以省略此步骤。
如果是 POST 请求,需要在这里发送请求体数据。
- abort():取消当前请求。
属性
1.readayState:请求的状态。
- 0:请求未初始化:尚未调用.open()方法。
- 1:启动:服务器连接已建立,已调用.open()方法,未调用.send()方法。
- 2:发送:已经调用.send()方法,但尚未接收到响应。
- 3:接收:已经接收到部分响应数据。
- 4:完成:请求已完成,且响应已就绪 ,已接收到全部响应数据,而且已可以在客户端使用。
2.status:HTTP 响应的状态码。
1xx
(临时响应):表示临时响应并需要请求者继续执行操作的状态码。2xx
(成功):表示成功处理了请求的状态码。3xx
(重定向):表示要完成请求,需要进一步操作。4xx
(请求错误):表示请求可能出错,妨碍了服务器的处理。5xx
(服务器错误):表示服务器在尝试处理请求时发生内部错误。这些错误可能是服务器本身的错误,而不是请求出错。
200
表示从客户端发来的请求在服务器端被正常处理了。204
表示请求处理成功,但没有资源返回。301
表示永久性重定向。该状态码表示请求的资源已被分配了新的URI,以后应使用资源现在所指的URI。302
表示临时性重定向。304
表示客户端发送附带条件的请求时(指采用GET
方法的请求报文中包含if-matched,if-modified-since,if-none-match,if-range,if-unmodified-since任一个首部)服务器端允许请求访问资源,但因发生请求未满足条件的情况后,直接返回304Modified(服务器端资源未改变,可直接使用客户端未过期的缓存)。400
表示请求报文中存在语法错误。当错误发生时,需修改请求的内容后再次发送请求。401
表示未授权(Unauthorized),当前请求需要用户验证。403
表示对请求资源的访问被服务器拒绝了。404
表示服务器上无法找到请求的资源。除此之外,也可以在服务器端拒绝请求且不想说明理由时使用。500
表示服务器端在执行请求时发生了错误。也可能是Web应用存在的bug或某些临时的故障503
表示服务器暂时处于超负载或正在进行停机维护,现在无法处理请求。
3.statusText:HTTP 响应的状态文本(例如,200—"OK",404—"Not Found")。
4.responseText:服务器返回的响应文本,表示为一个串。
5.responseXML:服务器返回的响应,表示为 XML ,解析为 XML Document 对象。如果响应不是有效的 XML ,则为 null 。
6.onreadystatechange:当 readyState 属性改变时触发的事件处理器。
五、GET 和POST 请求
GET
- GET 请求用于获取数据。
- GET 请求会把附加参数带在 URL 上,这些参数会显示在浏览器地址栏中,并且路由器会记录请求地址。由于参数暴露在 URL 中,GET 请求的隐私性和安全性较差。
- GET 请求能传递的数据量有限(因为URL的长度限制)。
- GET 请求只接受 ASCII 字符的参数数据类型。
- GET 请求参数会被完整保留在浏览器历史记录里。
- GET 请求只能进行url编码。
- GET 请求在浏览器回退时是无害的。
POST
- POST 请求用于提交数据。
- POST 请求会把提交数据放在报文内,也就是请求的消息体Request body中,而不是在URL中传递。这意味着数据对于用户来说是不可见的,因此POST请求相对更安全。
- POST请求没有长度限制。
- POST请求对于参数的数据类型没限制。
- POST请求参数不会被完整保留在浏览器历史记录里。
- POST请求支持多种编码方式。
- POST请求在浏览器回退时会再次提交请求。
六、JSON字符串和JSON对象的相互转换
//字符串转对象
const jsonString = '{"name": "John", "age": 30}';
const jsonObject = JSON.parse(jsonString);
console.log(jsonObject); // 输出: { name: 'John', age: 30 }
//对象转字符串
const jsonObject = { name: 'John', age: 30 };
const jsonString = JSON.stringify(jsonObject);
console.log(jsonString); // 输出: '{"name":"John","age":30}'
七、跨域
跨域请求(Cross-Origin Request),是指在Web开发中,当一个Web页面向不同源(域名、协议或端口)的服务器发起请求时,浏览器会遵循同源策略(Same-Origin Policy)的限制,对这些跨源请求进行限制。
同源:协议,域名,端口号全部相同,只要有一个不相同就是跨域。
不受同源策略限制的情况
- 页面中的链接,重定向,表单提交。
- 跨域资源的引入是可以的。但是js不能读写加载的内容。如嵌入到页面中的,,,等。
跨域解决方案
方法一,JSONP
利用 <script> 标签没有跨域限制的漏洞,通过动态创建 <script> 标签,然后设置其 src 属性为跨域 url 来实现。
步骤:
1.去创建一个 script 标签。
2.script 的 src 属性设置接口地址。
3.接口参数,必须要带一个自定义函数名,要不然后台无法返回数据。
4.通过定义函数名去接收后台返回数据。
<body>
用户名:<input type="text" id="username">
<p></p>
<script>
//获取input元素
const input = document.querySelector('input');
const p = document.querySelector('p');
//声明handle函数
function handle(data) {
input.style.border = "solid 2px #f00";
//修改p标签的提示文本
p.innerHTML = data.msg;
}
//绑定事件
input.onblur = function () {
//获取用户的输入值
let username = this.value;
//向服务器端发送请求 检测用户名是否存在
//1.创建script标签
const script = document.createElement('script');
//2.设置标签的src属性
script.src = 'http://127.0.0.1:8000/check-username';
//3.将script插入到文档中
document.body.appendChild(script);//插入到body标签的最后
}
</script>
</body>
//server.js中添加
//用户名检测是否存在
app.all('/check-username', (request, response) => {
// response.send('Hello jsonp');//对比这两个的控制台和网络response
// response.send('console.log("hello jsonp")');//script请求要的是函数调用的内容(js代码)返回
const data = {
exist: 1,
msg: '用户名已经存在'
};
//将数据转换为字符串
let str = JSON.stringify(data);
//返回结果
response.end(`handle(${str})`);//end不会加特殊响应头,`是tab键上面的,而不是单引号
//总结:返回结果的形式是函数调用,函数的参数是我们想给客户端返回的结果数据,注意函数需提前声明
});
方法二,CORS:跨域资源共享
服务器设置 Access-Control-Allow-OriginHTTP 响应头之后,浏览器将会允许跨域请求。
浏览器需要支持 HTML5 ,可以支持 POST ,PUT 等方法兼容 IE9 以上。
<body>
<button>发送请求</button>
<div id="result"></div>
<script>
const btn = document.querySelector('button');
btn.onclick = function () {
//1.创建对象
const x = new XMLHttpRequest();
//2.初始化设置
x.open("GET", "http://127.0.0.1:8000/cors-server");
//3.发送
x.send();
//4.绑定事件
x.onreadystatechange = function () {
if (x.readyState === 4) {
if (x.status >= 200 && x.status < 300) {
//输出响应体
console.log(x.response);
}
}
}
}
</script>
</body>
//在server.js中设置响应头
//cors
app.all('/cors-server', (request, response) => {
response.setHeader("Access-Control-Allow-Origin", "*");//*表示所有端口
response.setHeader("Access-Control-Allow-Headers", "*");
response.setHeader("Access-Control-Allow-Methods", "*");
response.send('hello CORS');
});
方法三,使用代理。
方法四,服务器端转发。
方法五,跨文档消息。