大多数人,都低估了编程学习的难度,而高估了自己的学习能力和毅力。
当前系列: Javascript入门 修改讲义
复习:Ajax,理解:“传统”的HTML请求,只会得到一个完整的HTML页面响应


iframe

可以实现“局部刷新”。

在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
        window.parent.document.getElementsByTagName('p')[0].innerText = "全程直播";
  • 父页面调用子页面需要:window.frames[n]
        window.frames[0].document.getElementsByTagName('div')[0]
            .setAttribute('style', "border: 1px dashed");


Ajax

Ajax发起的仍然是一个HTTP请求复习,所以仍然要遵守HTTP协议:

  • 客户端发起请求,服务器端响应
  • 无状态”,所以可以带cookie
  • ……

只是响应的内容通常是“HTML片段”,或JSON格式数据。

而HTTP请求的发起,依赖于:

XMLHttpRequest 对象

(现代浏览器)直接new出来就行:
let xhttp = new XMLHttpRequest();

接下来都围绕这XMLHttpRequest对象展开。

请求

Ajax需要由客户端主动发起:

open()

定义该Ajax请求的“特性”,可以有5个参数,依次为:
  • method:请求方式, 字符串GET或POST 复习
  • url:请求访问的文件路径,注意:通过url能够获得各种类型的响应,不仅仅是html/img/css等静态内容,还可以是……
    另外:出于安全原因,现代浏览器不允许跨域(域名,比如127.0.0.1和17bang.ren)访问。
  • async:true(异步,默认)或 false(同步,已经不推荐了)
  • user:(可选的)用户名称
  • psw:(可选的)密码

setRequestHeader()

设置“请求头”,给服务器更多的信息。比如:

  • 添加一个x-requested-with,便于服务器判断请求是否为Ajax发起(惯例)
    xhttp.setRequestHeader("x-requested-with", "xml"); 
  • 通常POST时还要设定content-type(使其同form表单提交),否则默认类型为text/plain,影响后台程序处理
    xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); 

send()

如果是GET请求,可以不用带参数,因为参数都可以在url中直接包含,如:

xhttp.open("GET", "/Ajax.html?id=8"); 
xhttp.send();

POST时通常把参数信息放在send()中,如:

xhttp.send("fname=Bill&lname=Gates");

演示:F12查看请求内容

onreadystatechange

@想一想@:能不能直接返回响应结果?比如:

let result = xhttp.send();

演示:send()方法没有返回值。

要想拿到服务器响应,需要利用事件,比如,onreadystatechange。 

将该事件绑定到XMLHttpRequest对象:

xhttp.onreadystatechange = function() {

readystate

可以利用其(this.)readyState:判断Ajax请求的状态:

xhttp.onreadystatechange = function () {
    console.log('in onreadystatechange:' + this.readyState);
};
  • 0: 请求未初始化,open()之前
  • 1: 服务器连接已建立,open()之后
  • 2: 请求已发送
  • 3: 等待服务器处理请求
  • 4: 请求已完成且响应已就绪

当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()方法是异步的。

因为send()的结果需要服务器的响应,但需要多久服务器才能响应呢?不知道。在等待服务器响应的这个时间段,JavaScript代码不会停在这里等着……

即:一旦完成send()方法,不需要等待send()的结果,就会立即执行后面的代码。

断点演示代码执行顺序:

xhr.send();
console.log("after send():" + xhr.readyState);

服务器响应

除了response,还可以通过this.

  • responseText(同response):获取服务器端响应
  • status:获取响应状态码(如200、404等)
  • statusText:status的文本描述

其他事件

还有:

  • onload(start/end):在加载(开始/结束)时触发,
    1. load和loadstart时,readyState =1;
    2. loadend时,readyState=4
  • onabort:在取消Ajax请求时触发
  • onerror:在发生网络(不是404,500等)错误时触发,演示跨域请求
    xhr.open("GET", "https://17bang.ren/");
    404/500之类的错误通常通过this.status等检查
    if(this.status !== "200"){


文件上传

复习:multipart/form-data

Ajax的文件上传,需要一些特殊的处理。首先需要一个(HTML5标准下的)

FormData()对象

可以直接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({


JSON

全称: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种类型:

  1. number:和JavaScript的number完全一致;
  2. boolean:就是JavaScript的true或false;
  3. string:就是JavaScript的string;
  4. null:就是JavaScript的null;
  5. array:就是JavaScript的Array表示方式——[];
  6. object:就是JavaScript的{ ... }表示方式

演示:Ajax请求获得JSON文件内容

xhr.open("GET", "/student.json");

xhr.onloadend = function () {
    console.log("this.readyState:" + this.readyState);
    console.log(typeof(this.response));

JavaScript提供了内置的方法:

parse()

反序列化,将获得的字符串格式的JSON内容转化成JavaScript对象(复习:序列化

    let laoChen = JSON.parse(this.response);
    console.log(typeof laoChen);

stringify

有时候(前端传后台)我们需要将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");


作业

  1. 根据Ajax动态加载导航栏下的“新消息”
  2. 分别通过iframe和Ajax完成侧边栏关键字“换一批”的功能
  3. 参考用户资料页面,将用户的输入,生成一个JSON字符串,POST到后台页面
  4. 后台准备一个profile.json文件,里面存储用户资料页面需要的json数据,在用户资料页面加载根据profile.json的内容填充表单数据
  5. 能通过JSON获得(有无未读消息的)数据,决定是否闪烁铃铛图标(注意:要能闪还能不闪,这就是所谓的“短轮询”)
  6. 参考注册页面
    1. 如果用户名重复(通过Ajax获得已有用户名的JSON数据),移出焦点时提示“用户名重复”。
    2. 重新输入用户名,一旦输入用户名部分没有重复,“用户名重复”的提示消失
    3. 用户名重复时,form表单不能提交
  7. 完成发布求助时的以下功能:
    1. 刷新帮帮币
    2. 关键字:
      1. 没有选择一级关键字,不能选择二级关键字
      2. 选择一级关键字后,通过Ajax获取到该一级关键字下的二级关键字,并予以显示
      3. 一级关键字和二级关键字被选中后,会显示在下拉列表上方
    3. 定向求助:移出焦点,就能查找到相关用户
学习笔记
源栈学历
键盘敲烂,月薪过万作业不做,等于没学

作业

觉得很 ,不要忘记分享哟!

任何问题,都可以直接加 QQ群:273534701

在当前系列 Javascript入门 中继续学习:

多快好省!前端后端,线上线下,名师精讲

  • 先学习,后付费;
  • 不满意,不要钱。
  • 编程培训班,我就选源栈

更多了解 加:

QQ群:273534701

答疑解惑,远程debug……

B站 源栈-小九 的直播间

写代码要保持微笑 (๑•̀ㅂ•́)و✧

公众号:源栈一起帮

二维码