【Web前端学习笔记】AJAX_原生AJAX,JQuery下的AJAX,跨域

来源:互联网 发布:网络安全技术的建议 编辑:程序博客网 时间:2024/05/21 17:27

AJAX

A.原生AJAX

1.概述

AJAX:Asynchronous JavaScript and XML,异步的JavaScript和XML

不是新的编程语言,而是一种使用现有标准的新方法

2.异步概念

客户端和服务端不必相互等待,而是进行一种并发的操作

用户在发送请求后继续当前工作:浏览或提交信息

在服务器响应完成后,AJAX引擎会将跟新的数据现实给用户


3.AJAX和传统应用区别(异步和同步区别)

AJAX使用的是异步,传统的Web使用的是同步

a.同步更新是需要对整个页面进行更新,并且以新页面的形式显示出来

b.异步更新是后台和服务器进行少量数据交换,即不重新加载整个网页就可以对网页的某部分进行更新,AJAX减少了用户的等待时间



4.优点

a.通过异步模式,网页无刷新,提升了用户体验

b.优化了浏览器和服务器之间的传输,减少不必要的数据往返,减少了带宽占用

c.AJAX引擎在客户端运行,承担了一部分本来由服务器承担的工作,从而减少了大用户量下的服务器负载

d.基于标准化的并被广泛支持的技术,不需要下载插件或者小程序

5.缺点

a.不支持浏览器的back按钮

b.安全问题:暴露了与服务器交互的细节

c.搜索引擎的支持比较弱

d.破坏了程序的异常机制

e.不容易调试

6.应用场景

a.请求的提交是为了页面数据显示,用户不希望看到网页的全部刷新

b.如果请求提交后,用户能从页面感觉到提交结果,最好使用AJAX技术

c.若请求提交后,用户不能从页面感觉到提交动作

d.复杂的UI,C/S模式

7.技术组成

a.HTML:用于建立Web表单并确定应用程序其他部分使用的字段

b.JS:实现AJAX应用程序的编程语言,帮助改进与服务器应用程序的通信

c.XMLHttpRequest对象:浏览器内置的数据异步发送和接收对象,是AJAX核心

是AJAX的基础,所有(IE5和IE6使用ActiveXObject)现代浏览器均支持

用于在后台与服务器交换数据,可以在不重新家在整个网页的情况下

对网页的某部分进行更新


d.文档对象模型DOM:用于处理HTML结构和服务器返回的XML

e.XML:数据传输格式,经常使用XML和JSON进行数据的交换

8.步骤

a.创建XMLHttpRequest对象

b.使用open()方法和服务器建立联系,传递方法类型,url地址,提交方式


GET:快

POST:

1)无法使用缓存文件(更新服务器上的文件或数据库)

2)向服务器发送大量数据(POST没有数据量限制)

3)发送包含未知字符的用户输入时,POST更稳定可靠

c.使用onreadystatechange属性设置回调函数,需要判断request和response状态码

接受服务端信息的触发函数,服务器会通知当前的通信状态

通过改变对象的readyState状态实现,每次改变都会触发该函数


d.使用send()方法发送请求

模拟一个注册用户名验证

1)前端代码

<!DOCTYPE html><html><head><meta charset="UTF-8"><title>AJAX</title></head><body><form action="#"><input type="text" name="uname" id="uname" /><span id="tip"></span><br><input type="button" id="btn" value="提交" /></form></body><script type="text/javascript">// 1)创建XMLHttpRequest对象function createXHR() {// 定义对象var xhr;// 跨浏览器支持判断if (window.XMLHttpRequest) {// 大多现代浏览器都内建对象xhr = new XMLHttpRequest();} else {// 老版本的(IE5和IE6)xhr = new ActiveXObject("Microsoft.XMLHTTP");}// 返回return xhr;}// 向服务器发送请求function sendRequest() {// 获取表单信息var name = document.getElementById("uname").value;// 调用创建对象var xhr = createXHR();// 和服务端进行关联:请求方式,文件服务器虚拟路径,异步(true)或同步(false)xhr.open("GET", "RegisterServlet?name=" + name, true);// 回调函数// 在发送前,需要定义接受服务端信息后的触发函数xhr.onreadystatechange = function() {process(xhr);}// 发送参数// GET不需要发送,直接为空xhr.send(null);}// 回调函数function process(xhr) {// 当readyState为4,并且status为200if(xhr.readyState == 4 && xhr.status == 200){// 获取响应信息var msg = xhr.responseText;// 判断if(msg == "yes") {document.getElementById("tip").innerHTML = "<font color='green'>用户名可用</font>";} else if(msg == "no") {document.getElementById("tip").innerHTML = "<font color='red'>用户名已存在</font>";}}}// 当点击按钮,触发发送异步请求document.getElementById("btn").onclick = sendRequest;</script></html>

2)后台

package org.xxxx.demo01;import java.io.IOException;import java.io.PrintWriter;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;@WebServlet("/RegisterServlet")public class RegisterServlet extends HttpServlet {private static final long serialVersionUID = 1L;protected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {// 获取参数String name = request.getParameter("name");// 非空name = (name != null) ? name : "";// 获取输出流PrintWriter writer = response.getWriter();// 判断if (name.equals("zhangsan")) {writer.write("no");} else {writer.write("yes");}}protected void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doGet(request, response);}}
3)运行服务器,测试

a)情况1


b)情况2


9.responseText

是XMLHttpRequest对象的一个属性,封装了服务端返回的字符串形式数据

a.普通字符串,客户端直接当作普通文本处理

b.JSON格式:使用{}包含的文本

文件类型:.json

文本MIME类型:application/json

10.JSON中数据的赋值和获取

因为JSON使用JS语法,所以无需额外的软件就能处理JS中的JSON

<script type="text/javascript">function() {var employees = [{"firstName" : "Bill", "lastName" : "Gates"},{"firstName" : "George", "lastName" : "Bush"}];// 给第一组赋值employees[0].lastName = "Jobs";// 取值employees[0].lastName;}</script>

11.服务端JSON数据的使用

接收的服务器数据是JSON字符串,可以使用JSON.parse()方法将数据转换为JS对象

服务端必须确保json格式正确性:"{\"name\" :\" "+ name"\", \"pass\" : 123456}";

客户端获取:var str = JSON.parse(xmlHttp.responseText);

需求:获取用户名,响应用户名和密码的JSON格式字符串

a.前端

<!DOCTYPE html><html><head><meta charset="UTF-8"><title>Insert title here</title></head><body><form action="#"><input type="text" name="uname" id="uname"><span id="tip"></span><br /><input type="button" id="btn" value="提交"></form></body><script type="text/javascript">// 创建XMLHttpRequest对象function createXHR(){var xhr;if (window.XMLHttpRequest) {xhr = new XMLHttpRequest();} else {xhr = new ActiveXObject("Microsoft.XMLHTTP");}return xhr;}// 发送请求function sendRequest(){var name = document.getElementById("uname").value;var xhr = createXHR();// 和服务端关联xhr.open("POST", "JSONServlet", true);// 回调xhr.onreadystatechange = function() {process(xhr);}// POST请求必须添加以下代码xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");// 发送参数:POST方式参数键值对必须写在sendxhr.send("name=" + name);}// 回调函数function process(xhr) {if(xhr.readyState==4&&xhr.status==200) {// 转换json字符串为一个js对象var user = JSON.parse(xhr.responseText);document.getElementById("tip").innerHTML = user.name + "==" + user.pass;}}document.getElementById("btn").onclick = sendRequest;</script></html>

b.后台

package org.xxxx.demo01;import java.io.IOException;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;@WebServlet("/JSONServlet")public class JSONServlet extends HttpServlet {private static final long serialVersionUID = 1L;protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// 设置响应为JSONresponse.setContentType("application/json;charset=utf-8");// 获取参数String name = request.getParameter("name");// 非空判断if (name != null) {// 响应  {"name":"name","pass":"123456"}response.getWriter().write("{\"name\":\"" + name + "\",\"pass\":\"123456\"}");}}protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}}

3)结果


12.解析XML内容

服务端返回xml数据时,必须设置

response.setContentType("text/xml;charset=utf-8");

1)前端

<!DOCTYPE html><html><head><meta charset="UTF-8"><title>Insert title here</title></head><body><form action="#"><input type="text" name="uname" id="uname"><span id="tip"></span><br /><input type="button" id="btn" value="提交"></form></body><script type="text/javascript">// 创建对象function createXHR() {var xhr;if (window.XMLHttpRequest) {xhr = new XMLHttpRequest();} else {xhr = new ActiveXObject("Microsoft.XMLHTTP");}return xhr;}// 发送请求function sendRequest() {var name = document.getElementById("uname").value;var xhr = createXHR();// 关联服务器xhr.open("POST", "XMLServlet", true);// 回调xhr.onreadystatechange = function() {process(xhr);}// 设置响应头xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");// 发送xhr.send("name=" + name);}// 回调函数function process(xhr) {if(xhr.readyState==4&&xhr.status==200){    //返回responseXML的dom对象    var name = xhr.responseXML.getElementsByTagName('name')[0].firstChild.nodeValue;    var pass = xhr.responseXML.getElementsByTagName('pass')[0].firstChild.nodeValue;    document.getElementById('tip').innerHTML =  name + "==" + pass;      }}document.getElementById('btn').onclick = sendRequest;</script></html>

2)后台

package org.xxxx.demo01;import java.io.IOException;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;@WebServlet("/XMLServlet")public class XMLServlet extends HttpServlet {private static final long serialVersionUID = 1L;protected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {// 设置响应头response.setContentType("text/xml;charset=utf-8");// 响应response.getWriter().write("<user><name>张三</name><pass>123456</pass></user>");}protected void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doGet(request, response);}}

3)结果


13.参数传递

a.GET:需要再URL后添加参数信息

b.POST:需要再body中传递参数

c.中文乱码问题:tomcat8.5以上不会出现,低版本需要解码

14.练习

省市二级联动

a.前端

<!DOCTYPE html><html><head><meta charset="UTF-8"><title>省市二级联动</title></head><body><form action="#"><select id="provs"><option value="1">山西省</option><option value="2">陕西省</option><option value="3">湖北省</option></select><select id="cities"></select></form></body><script type="text/javascript">// 创建对象function createXHR() {var xhr;if (window.XMLHttpRequest) {xhr = new XMLHttpRequest();} else {xhr = new ActiveXObject("Microsoft.XMLHTTP");}return xhr;}// 发送请求function sendRequest() {var pid = document.getElementById("provs").value;var xhr = createXHR();// 关联服务端xhr.open("GET", "SelectServlet?pid=" + pid, true);// 回调xhr.onreadystatechange = function() {process(xhr);}// 发送参数xhr.send(null);}// 回调function process(xhr) {if (xhr.readyState == 4 && xhr.status == 200) {// 解析成JSON对象var jsonObjs = JSON.parse(xhr.responseText);var len = jsonObjs.length;var citis = document.getElementById("cities");// 下拉框清零citis.options.length = 0;for(var i = 0; i < len; i++) {var obj = jsonObjs[i];// 创建optionvar option = new Option(obj.name, obj.id);citis.appendChild(option);}}}document.getElementById('provs').onchange = sendRequest;</script></html>

b.后台

package org.xxxx.demo01;import java.io.IOException;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;@WebServlet("/SelectServlet")public class SelectServlet extends HttpServlet {private static final long serialVersionUID = 1L;protected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {// 设置response.setContentType("application/json;charset=UTF-8");// 获取参数String pid = request.getParameter("pid");String jsonStr = "";// 判断if (pid.equals("1")) {jsonStr = "[{\"id\":1,\"name\":\"太原\"}, {\"id\":2,\"name\":\"运城\"}, {\"id\":3,\"name\":\"临汾\"}]";} else if (pid.equals("2")) {jsonStr = "[{\"id\":1,\"name\":\"西安\"}, {\"id\":2,\"name\":\"延安\"}, {\"id\":3,\"name\":\"宝鸡\"}]";} else if (pid.equals("3")) {jsonStr = "[{\"id\":1,\"name\":\"武汉\"}, {\"id\":2,\"name\":\"襄阳\"}, {\"id\":3,\"name\":\"宜昌\"}]";}// 响应response.getWriter().write(jsonStr);}protected void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doGet(request, response);}}

c.结果


B.JQuery下的AJAX

1.概述

JQuery提供了几个用于发送AJAX请求的函数

其中最核心也是最复杂得是JQuery.ajax(options)

所有的其他Ajax函数都是它的一个简化调用

当我们想要完全控制AJAX时可以使用此结果

否则还是使用简化方法如get,post,load等更加方便

2.ajax()方法

一般格式

$.ajax({

    type:POST,    可选,默认为GET

    url:url,            必选,请求的发送url

    data:data,      可选,发送的数据

    dataType:dataType    可选,预期返回的数据类型

    success:sucHandler   可选,请求成功执行的函数

    error:errorHandler      可选,请求失败执行的函数

});

<!DOCTYPE html><html><head><meta charset="UTF-8"><title>Insert title here</title><script type="text/javascript" src="js/jquery.js"></script></head><body><form action="#"><input type="text" name="uname" id="uname"><span id="tip"></span><br /><input type="button" id="btn" value="提交"></form></body><script type="text/javascript">$(document).ready(function() {$("#btn").on("click", function() {$.ajax({"url":"RegisterServlet","data":{"name":$("#uname").val()},"success":function(data) {document.getElementById("tip").innerHTML = data;},"error":function(XMLHttpRequest, textStatus, errorThrown) {alert(textStatus);}});});});</script></html>

3.参数详解

a.data

要求为Object或String类型的参数,发送到服务器的数据

对象必须为key/value格式

b.success

要求为function类型的函数,是请求成功后调用的回调函数

有两个参数function(data, textStatus)

1)有服务器返回,并根据dataType参数进行处理后的数据

2)描述状态的字符串

c.error

要求为function类型的函数,是请求失败后调用的回调幻术

有三个参数function(XMLHttpRequest, textStatus, errorThrown)

通常情况下,textStatis和erroeThrown只有一个包含信息

4.ajax()方法参数传递方式

a.拼接字符串

data:"name=" + val

b.拼接在url后面

url:"loginServlet?name=" + name

c.json

data:{

     name:name,

     password:pass

}

d.序列化表单内容为字符串

data:$("#form1").serialize();

5.get()方法

get(url, [data], [callback])

通过远程HTTP GET请求再入信息,是一个简单的GET

请求功能以取代复杂$.ajax,请求成功时可调用回调函数

如果需要在出错时执行函数,请使用$.ajax

url(String):逮载入页面的URL地址

data(Map):可选,带发送key=value参数

callback(fucntion):可选,再入成功时回调函数

<!DOCTYPE html><html><head><meta charset="UTF-8"><title>Insert title here</title><script type="text/javascript" src="js/jquery.js"></script></head><body><form action="#"><input type="text" name="uname" id="uname"><span id="tip"></span><br /><input type="button" id="btn" value="提交"></form></body><script type="text/javascript">$(document).ready(function() {$("#btn").on("click", function() {$.get("RegisterServlet", "name=" + $("#uname").val(), function(data) {document.getElementById("tip").innerHTML = data;});});});</script></html>

6.post()方法

post(url, [data], [callback])

一个简单的post请求功能以取代复杂$.ajax

用法与get()方式相同

<!DOCTYPE html><html><head><meta charset="UTF-8"><title>Insert title here</title><script type="text/javascript" src="js/jquery.js"></script></head><body><form action="#"><input type="text" name="uname" id="uname"><span id="tip"></span><br /><input type="button" id="btn" value="提交"></form></body><script type="text/javascript">$(document).ready(function() {$("#btn").on("click", function() {$.post("RegisterServlet", "name=" + $("#uname").val(), function(data) {document.getElementById('tip').innerHTML = data; });});});</script></html>

C.跨域

1.概述

不同的域之间相互请求资源,就叫跨域(跨服务器)

2.域名地址组成

http://www.baidu.8080/script/jquery.js

http://协议类型

www:子域名

baidu:主域名

script/jquery.js请求的地址

3.跨域的JS支持


当协议、子域名、主域名、端口号中任意一个不想同时,都算不同的域

浏览器安全的基石是“同源政策”,为了保证用户信息的安全,防止网站窃取数据

同源政策规定AJAX请求只能发给同源地址,否则报错

随着会联网的发展,如果非同源,有三种行为受到限制

a.Cookie,LocalStorage和IndexDB无法读取

b.DOM无法获得

c.AJAX请求不能发送

虽然这些限制是必要的,但有时很不方便

4.JSONP

JSON with Padding:是json的一种使用模式

可以让网页从别的域名那获取资料,即跨域读取数据

是一种非正式传输协议,允许用户传递一个callback参数给服务端

然后服务端返回数据时会将这个callback参数作为函数名来包裹JSON数据

这样客户端可以随意指定自己的函数来自动处理返回数据

但是script标签是一个例外

通过script标签访问不同域的资源则不受限制

利用<script>元素的这个开方策略,网页可以得到从高其他来源动态产生的JSON资料

而这种使用模式就是所谓的JSONP

用JSONP抓到的资料并不是JSON,而是任意的JS

用JS解析器执行而不是用JSON解析器解析

5.实现

调用不同域的js

调用不同域的servlet(打开两个tomcat)

<!DOCTYPE html><html><head><meta charset="UTF-8"><title>Insert title here</title><script type="text/javascript" src="js/jquery.js"></script></head><body><form action="#"><input type="text" name="uname" id="uname"><span id="tip"></span><br /><input type="button" id="btn" value="提交"></form></body><script type="text/javascript">$(document).ready(function() {$("#btn").on("click", function() {// jsonp$.ajax({"type":"GET","url":"http://loaclhost:8081/my/InfoServlet", //开启另一个端口为8081的tomcat"dataType":"jsonp","succcess":function(data) {alert("success");}});// 简写$.getJSON("http://localhost:8081/my/InfoServlet?callback=?", function(data) {alert(data);});});});</script></html>


原创粉丝点击