Ajax day-01

目录

一. Ajax

1.1 创建XMLHttpRequest对象

1.2 Ajax向服务器发送请求

1.3 设置http请求头

1.4 发送请求

1.5 获得响应

1.6 监听请求状态的改变

1.7 获取响应头

1.8 获得响应主体

1.9 处理服务器返回的数据

1.10 怎样向服务器传递数据?

二. 接口文档

三. 开发模式

3.1 前后端混合

3.2 前后端分离

3.3 跨域和同源策略

3.4 JSONP实现跨域请求


一. Ajax

Ajax是Asynchronous Javascript And XML(异步JavaScript和XML)的缩写。

Ajax技术描述了使用脚本操纵HTTP和Web服务器进行数据交换,在页面不刷新的情况下,实现页面的局部更新。

重点:

  • Ajax 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。

  • 通过在后台与服务器进行少量数据交换,Ajax 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。

  • 传统的网页(不使用 Ajax)如果需要更新内容,必须重载整个网页页面。

1.1 创建XMLHttpRequest对象

浏览器在XMLHttpRequest类上定义了它的HTTP方法。这个类型的每个实例都表示一个独立的请求/响应对,并且这个对象的属性和方法允许指定请求细节和获取相应数据。

创建XMLHttpRequest对象:

var xhr = new XMLHttpRequest();

回忆:

一个HTTP请求由4部分组成:

  • HTTP请求方法(GET/POST等)

  • 请求的URL

  • 一个可选的请求头集合,其中可能包含身份验证信息

  • 一个可选的请求主体

1.2 Ajax向服务器发送请求

创建XMLHttpRequest对象之后,我们就可以使用XMLHttpRequest对象的open()方法发起请求,该方法必须要指定请求方法(GET、POST等)和URL。

xhr.open("GET", "home.html");
xhr.open('method', 'URL' [, asyncFlag [, 'userName' [, 'password']]])
  • method:用于指定请求方式,如GET、POST,不区分大小写。 URL:表示请求的地址。 asyncFlag:可选参数,用于指定请求方式,同步请求为false,默认为异步请求true。 userName和password:可选参数,表示HTTP认证的用户名和密码。

  • 请求方法不区分大小写,但通常都写成大写的形式。除了"GET"和"POST"之外,该方法还支持"DELETE"、"HEAD"、"OPTIONS"和"PUT"作为第一个参数。但"TRACE"和 "CONNECT"由于安全风险已被明确禁止使用。

  • URL用来指定请求的资源。它可以是一个相对URL(相对于当前文档的URL),也可以是一个绝对URL。如果使用的是绝对URL,则协议、主机和端口通常必须要与当前文档URL保持一致,因为跨域的请求通常会报错(在服务器允许跨域请求时,则不会报错)。

注意:

同步和异步的区别:是否阻塞代码的执行。

异步方式(默认):是非阻塞的,浏览器端的JavaScript程序不用等待Web服务器响应,可以继续处理其他事情。当服务器响应后,再来处理Ajax对象获取到的响应结果。下面请看异步的执行过程,

同步方式:是阻塞的,当Ajax对象向Web服务器发送请求后,会等待Web服务器响应的数据接收完成,再继续执行后面的代码。

1.3 设置http请求头

除了设置请求方法和URL以外,我们还可以设置请求头。POST请求一般是要用"Content-Type"请求头指定请求主体的MIME类型(用来描述实体内容的编码格式):

xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");//默认编码格式(数据被编码为名称/值对) 
xhr.setRequestHeader("Content-Type", "application/json");//用来告诉服务端消息主体是序列化后的 JSON 字符串

扩展阅读:Form表单的编码类型

但是有些请求头我们不能自己指定,例如"Content-Length"、"Date"、"Referer"、"User-Agent"等,XMLHttpRequest将自动添加这些头,防止伪造它们。除此之外,XMLHttpRequest对象自动处理Cookie、连接时间、字符集和编码判断,所以我们无法向setRequestHeader()传递如下的请求头:

Accept-CharsetContent-Transfer-EncodingTE
Accept-EncodingDateTrailer
ConnectionExpectTransfer-Encoding
Content-LengthHostUpgrade
CookieKeep-aliveUser-Agent
Cookie2RefererVia

1.4 发送请求

使用XMLHttpRequest发起请求的最后一步是指定可选的请求主体并将它发送给服务器。

xhr.send(content);//Open的方式是post
xhr.send(null);//open的方式是get的一般不用send
//xhr.send('clazz=火花&name=张三&gender=男');

GET请求没有请求体,所以应该传递null或省略这个参数。而POST请求通常具有请求主体,同时它应该与使用setRequestHeader()指定的"Content-Type"一致。

1.5 获得响应

一个完整的HTTP响应消息由状态行、响应头、空行和响应主体组成。这些都可以通过XMLHttpRequest对象的方法和方法获取。

1.6 监听请求状态的改变

为了在响应准备就绪时得到通知,必须监听XMLHttpRequest对象上的onreadystatechange事件。

xhr.onreadystatechange = function(){
​
};

但为了理解这个事件类型,我需要先弄明白readyState属性。readyState属性的值是一个整数,用来指示HTTP请求的状态。readyState属性的值如下表所示:

常量含义
UNSENT0初始化,尚未调用open()方法
OPENED1启动,已调用open()方法,但尚未调用send()方法
HEADERS_RECEIVED2发送,已调用send()方法,接收到响应头信息
LOADING3接收中,已经接收到部分响应主体
DONE4完成,已经接收到全部响应数据,而且已经可以在客户端使用了

在实际应用中,当readyState属性的值改变为0或1时可能不会触发这个事件。当readyState属性的值改变为4或服务器的响应完成时,所有的浏览器都会触发readystatechange事件。因此为了判断响应是否真正完成了,我们应该在事件处理程序中时刻检测readyState属性的值。

xhr.onreadystatechange = function(){
if (xhr.readyState === 4) {
        console.log("请求完成了");
    }
};

但这样只能确保请求完成了,并不能确保请求成功。因此我们还需要根据响应的【状态码】来判断请求是否成功。

我们可以通过XMLHttpRequest对象的status和statusText属性获取HTTP状态码,状态消息。

xhr.status       // 200
xhr.statusText   // OK

代码如下:

xhr.onreadystatechange = function(){
if (xhr.readyState === 4 && xhr.status === 200) {
        console.log("请求完成并且成功了");
    }
};

完善的判断信息

xhr.onreadystatechange = function(){
    if (xhr.readyState === 4) {
            if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
                alert(xhr.responseText);
            } else {
                alert("Request was unsuccessful: " + xhr.status);
            };
        };
};

1.7 获取响应头

  • 响应头用于告知客户端本次响应的基本信息,包括服务器程序名、内容的编码格式、缓存控制等。请求头和响应头是浏览器和服务器之间交互的重要信息,由程序自动处理,通常不需要人为干预。

  • 使用getResponeHeader()和getAllResponeHeaders()获取响应头信息。

xhr.getResponeHeader("Content-Type")      // "text/html"
xhr.getAllResponeHeaders()              // 获取所有的响应头

1.8 获得响应主体

服务器的响应实体内容有多重编码格式,当用户请求的是一个网页,实体内容的格式就是HTML,如果请求的是图片响应的就是图片,服务器为了告知浏览器内容类型,会通过响应头中的Content-type字段来描述,这是一种MIME常见的类型。

无论响应主体内容类型是什么,响应主体的内容都会保存到responseText和responseXML属性中;而对于非XML数据而言responseXML属性的值将为null。

xhr.responseText     // 服务器端返回的文本内容

1.9 处理服务器返回的数据

服务器返回的数据都是JSON格式的字符串,为了使用方便,我们需要先把字符串转换成JavaScript对象(Object/Array)。

JSON.parse(xhr.responseText);

转换之后,就能以访问对象属性的方式拿到各种数据,实例如下:

// 转换成Object类型的对象
[{"id":"0001""name":"zhangsan","age":25,"gender":true,"phone":"12342344533"}]

// 转换成Array类型的对象
[
{"id":"0001""name":"zhangsan","age":25,"gender":true,"phone":"12342344533"},
{"id":"0001""name":"zhangsan","age":25,"gender":true,"phone":"12342344533"},
{"id":"0001""name":"zhangsan","age":25,"gender":true,"phone":"12342344533"},
{"id":"0001""name":"zhangsan","age":25,"gender":true,"phone":"12342344533"}
]

1.10 怎样向服务器传递数据?

GET方式的请求:

传递给后台的数据要拼接到URL的后面,以问号(?)开始,参数是以name=value的形式出现,每两个键值对之间以(&)分隔。例如:

'http://192.168.0.101:8080/AjaxDemo/LoginServlet?username=zhangsan&password=123456' 

POST方式的请求:

先通过请求头(Content-Type)指定数据的格式类型,常用的格式类型有两种,分别是:

  • application/x-www-form-urlencoded:用来告诉服务端消息主体是经过 URL编码的字符串(窗体数据被编码为名称/值对)

  • application/json :用来告诉服务端消息主体是序列化后的 JSON 格式的字符串

  • xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
    xhr.setRequestHeader("Content-Type","application/json");

  
然后将编码之后的数据通过send()方法传递给服务器,例如:

xhr.send(“clazz=%E7%81%AB%E8%8A%B112%E6%9C%9F&name=%E9%99%88%E6%A2%A6%E9%BE%99&gender=%E7%94%B7&age=20&hobby=%E7%9D%A1%E8%A7%89&hobby=%E6%89%93%E8%B1%86%E8%B1%86&tel=13834569928&address=%E5%8D%97%E9%98%B3&remark=%E6%96%B0%E5%90%8C%E5%AD%A6&date=2019-08-01”)。

二. 接口文档

在实际的项目开发中,后台服务写好之后,后台人员会给前台人员一份【接口文档】,文档中列出了每个功能所需要的接口信息,我们前台人员只需要根据文档的要求与服务器进行数据交互即可。接口文档示例如下:

接口请求方式作用请求参数
/api/student/getStudentGET1、获取所有学生信息 2、根据ID获取学生信息 3、根据name获取学生信息可选参数: id 学生ID name 学生姓名
/api/student/removeStudentGET1、根据ID删除学生信息必传参数: id 学生ID
/api/student/addStudentPOST1、添加学生信息必传参数: clazz班级 name 姓名 gender 性别 age 年龄 tel 电话 address 地址信息 remark 备注信息
/api/student/updateStudentPOST1、更新学生信息必传参数:id 学生ID clazz班级 name 姓名 gender 性别 age 年龄 tel 电话 address 地址信息 remark 备注信息**

三. 开发模式

3.1 前后端混合

前端代码与后台代码混合编写,也就是说前端代码和后台代码同时出现在一个文件中。例如,index.php文件是由PHP代码和HTML代码混写的:

<!DOCTYPE html>
<html>
<body>
<?php
$x=5; // global scope
function myTest() {
   $y=10; // local scope
   echo "<p>在函数内部测试变量:</p>";
   echo "变量 x 是:$x";
   echo "<br>";
   echo "变量 y 是:$y";
} 

myTest();

echo "<p>在函数之外测试变量:</p>";
echo "变量 x 是:$x";
echo "<br>";
echo "变量 y 是:$y";
?>
</body>
</html>

//再例如,index.jsp是由 Java代码和HTML代码混写的:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<html>
<head>
<title>life.jsp</title>
</head>
<body>

在前后端不分离的时代,在项目开发阶段,前端人员负责编写HTML页,后端人员负责写接口,前端人员调试页面动态数据都需要后端人员的配合,不能单独调试,耗时耗力。前端把前后端代码存放于同一个代码库中,甚至是同一工程目录下。页面中还夹杂着后端代码。前后端工程师进行开发时,都必须把整个项目导入到开发工具中。

3.2 前后端分离

随着时代的发展,渐渐的许多大中小公司开始把前后端的界限分的越来越明确,前端工程师只管前端的事情,后端工程师只管后端的事情。

  • 前后端分离情形一

前端资源和后台接口位于同一个服务器

  • 前后端分离情形二

前台资源和后台接口分别位于不同的服务器(跨域)

3.3 跨域和同源策略

例如【前后端分离情形二】浏览器不允许一个服务器中的页面向另一个服务器发送请求,错误信息如下:

我们通常称这种类型的请求叫跨域请求

为什么会跨域呢?

  • 因为违背了同源策略的请求就形成了跨域。

那什么是同源策略呢?

是指协议,域名,端口号相同就称为同源,同源的请求是允许的,如果非同源,那么在请求数据时,浏览器会在控制台中报一个异常,提示拒绝访问,就造成了跨域。

那怎么样解决这个问题呢?

为使受信任的网站之间能够跨域访问,HTML5提供了一个新的策略,就是Access-Control-Allow-Origin响应头。目标服务器通过该响应头可以指定允许来自特定URL的跨域请求,其值可以设置为任意URL或特定URL等。

实现方式有:

1、通过设置后台服务器允许跨域请求

2、JSONP

3、使用代理服务器

4、前台使用代理

3.4 JSONP实现跨域请求

Jsonp(JSON with Padding) 是 json 的一种"使用模式",可以让网页从别的域名(网站)那获取资料,即跨域读取数据。我们可以通过使用 html的script标记来进行跨域请求,并在响应中返回要执行的script代码,其中可以直接使用JSON传递javascript对象。这种跨域的通讯方式称为JSONP。

  • JSONP:遵循浏览器的同源策略基础上实现跨域请求的一种方式。 原理:与XMLHttpRequest无关,是利用<script>标签的src属性实现了跨域请求。 问题:在浏览器中, 哪些标签可以加载跨域资源? 答案:<script>、<img>、<iframe>、<link>等标签。

  • JSONP之所以采用<script>标签,是因为该标签加载的资源可以直接当做JavaScript代码执行,只要通过服务器端的配合,就可以传送数据。

    注意:

    JSONP本质上是加载了其他网站的脚本,这种方式存在安全风险,因为 其他网站可以利用JavaScript窃取用户信息,或更改页面内容。因此,在加载脚本前,一定确保对方是受信任的网站。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值