可以实现“局部刷新”。
在Ajax流行之前大量使用,在Ajax之后仍然在使用(演示:富文本编辑器/B站内嵌视频代码)
<iframe src="/keywords1.html" id="keywords" style="border:0px;"></iframe>
iframe中的src属性指定的就是一个独立的页面url地址,iframe中呈现的就是这个页面的内容。
通过改变src的值,我们就可以轻松的改变iframe中的内容:(类似的,验证码刷新也是同样的手段,这不是Ajax)
document.getElementById('keywords').src = "/keywords2.html";
演示:绑定到事件
注意,iframe加载的是一个独立的页面,所以子页面无法直接调用父页面的内容
window.parent.document.getElementsByTagName('p')[0].innerText = "全程直播";
window.frames[0].document.getElementsByTagName('div')[0] .setAttribute('style', "border: 1px dashed");
Ajax发起的仍然是一个HTTP请求(复习),所以仍然要遵守HTTP协议:
只是响应的内容通常是“HTML片段”,或JSON格式数据。
而HTTP请求的发起,依赖于:
let xhttp = new XMLHttpRequest();
接下来都围绕这XMLHttpRequest对象展开。
设置“请求头”,给服务器更多的信息。比如:
xhttp.setRequestHeader("x-requested-with", "xml");
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
如果是GET请求,可以不用带参数,因为参数都可以在url中直接包含,如:
xhttp.open("GET", "/Ajax.html?id=8"); xhttp.send();
POST时通常把参数信息放在send()中,如:
xhttp.send("fname=Bill&lname=Gates");
演示:F12查看请求内容
@想一想@:能不能直接返回响应结果?比如:
let result = xhttp.send();
演示:send()方法没有返回值。
要想拿到服务器响应,需要利用事件,比如,onreadystatechange。
将该事件绑定到XMLHttpRequest对象:
xhttp.onreadystatechange = function() {
可以利用其(this.)readyState:判断Ajax请求的状态:
xhttp.onreadystatechange = function () { console.log('in onreadystatechange:' + this.readyState); };
当readyState为4的时候,我们才能通过this.response获得服务器响应:
if(this.readyState == 4){ let keywords = document.getElementById("keywords"); keywords.innerHTML = this.response;在此之前,我们通常:
keywords.innerHTML = "请稍等……"
let btn = document.getElementsByTagName('button')[0]; //想一想:这里的btn能不能用this代替? btn.style.display = "none";
因为send()的结果需要服务器的响应,但需要多久服务器才能响应呢?不知道。在等待服务器响应的这个时间段,JavaScript代码不会停在这里等着……
即:一旦完成send()方法,不需要等待send()的结果,就会立即执行后面的代码。
断点演示代码执行顺序:
xhr.send(); console.log("after send():" + xhr.readyState);
除了response,还可以通过this.
还有:
xhr.open("GET", "https://17bang.ren/");404/500之类的错误通常通过this.status等检查
if(this.status !== "200"){
Ajax的文件上传,需要一些特殊的处理。首先需要一个(HTML5标准下的)
可以直接new处理:
let data = new FormData(),
然后取出要上传的文件内容:
//文件上传时可以选择多个文件 files = $(':file')[0].files;
再将文件内容附着(append)到FormData对象:
data.append('icon', files[0]);
然后调用JQuery Ajax发起请求。
另:如果后台一次请求只能处理一个文件,多个文件就要发起多次Ajax请求
for (let i = 0; i < files.length; i++) { data.append('icon', files[i]); $.ajax({
全称:JavaScript Object Notation
一种文本格式标准(同HTML或XML格式标准),作为XML的替代品,已经风靡全球,原因很简单:简单(复习KISS原则)
很多时候,从服务器端获得的数据都是JSON格式的;甚至有时候,前端发送到后端的数据都可以是JSON格式的。
一个标准的Json序列化示例:
{ "name": "老程", "age": 21, "isFemale": true, "hobby": [ "tabletennis", "basketball", "swim" ], "course": { "C#": 86, "HTML/CSS/JavaScript": 95, "SQL": 92, "ASP.NET": null } }
JSON文件统一为UTF-8编码,包含6种类型:
演示:Ajax请求获得JSON文件内容
xhr.open("GET", "/student.json"); xhr.onloadend = function () { console.log("this.readyState:" + this.readyState); console.log(typeof(this.response));
JavaScript提供了内置的方法:
反序列化,将获得的字符串格式的JSON内容转化成JavaScript对象(复习:序列化)
let laoChen = JSON.parse(this.response); console.log(typeof laoChen);
有时候(前端传后台)我们需要将JavaScript对象,转为字符串:
let laoCheng = { name: '老程', age: 21, isFemale: true, hobby: ['tabletennis', 'basketball', 'swim'], course: { 'C#': 86, 'HTML/CSS/JavaScript': 95, SQL: 92, 'ASP.NET': null } };
这就需要调用stringfy()方法:
console.log(JSON.stringify(laoCheng));
指定只序列化age属性
console.log(JSON.stringify(laoCheng, ['age']));某些情况可能还需要格式化,换行和缩进:
console.log(JSON.stringify(laoCheng, null, ' '));#观察#:除 array 以外,不保证各属性的顺序。
甚至传入传入回调函数 function(key, value) 进行自定义的处理:
console.log(JSON.stringify(laoCheng, function (key, value) { if (typeof value === 'string') {//key:属性,value:属性值 return value.toUpperCase(); } return value; }));
最应该小心的,其实还是undefined、NaN……这些玩意!
向后台发送JSON数据需要修改content type:
xhttp.setRequestHeader("Content-type", "application/json; charset=utf-8");
多快好省!前端后端,线上线下,名师精讲
更多了解 加: