以前觉得异步跟同步是一个很高深的学问,后来才发现就是一门学问,深不深的看人而已;
什么是—>>同步交互
就是用户在浏览器上所有动作都操作完毕后再将信息发送给服务器端,然后服务器端做出响应返回给浏览器数据;
大体逻辑是这样的------>>
同步交互的优点
可以保留浏览器后退按钮的正常功能。在动态更新页面的情况下,用户可以回到前一个页面状态,浏览器能记下历史记录中的静态页面,用户通常都希望单击后退按钮时,就能够取消他们的前一次操作,同步交互可以实现这个需求.
同步交互的缺点
1同步交互的不足之处,会给用户一种不连贯的体验,当服务器处理请求时,用户只能等待状态,页面中的显示内容只能是空白。
2因为已经跳转到新的页面,原本在页面上的信息无法保存,好多信息需要重新填写
什么是—>>异步交互
指发送一个请求,不需要等待返回,随时可以再发送下一个请求,即不需要等待。
大体逻辑是这样的---->>>
优点
1前端用户操作和后台服务器运算可以同时进行,可以充分利用用户操作的间隔时间完成运算
2页面没有跳转,响应回来的数据直接就在原页面上,页面原有信息得以保留
缺点
可能破坏浏览器后退按钮的正常行为。在动态更新页面的情况下,用户无法回到前一个页面状态,这是因为浏览器仅能记录的始终是当前一个的静态页面。用户通常都希望单击后退按钮,就能够取消他们的前一次操作,但是在AJAX这样异步的程序,却无法这样做。
什么是AJAX?
AJAX 即
“Asynchronous Javascript And XML”(异步 JavaScript和 XML),是指一种创建交互式、快速动态网页应用的网页开发技术,无需重新加载整个网页的情况下,能够更新部分网页的技术。通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。
AJAX关键技术
使用CSS构建用户界面样式,负责页面排版和美工
使用DOM进行动态显示和交互,对页面进行局部修改
使用XMLHttpRequest异步获取数据
使用JavaScript将所有的元素绑定在一起
简单的写了一个异步交互的小案例—>
我们很常见的一个案例-----用户注册时会提示用户名可用后者不可用;
先看效果图—>>>
部分代码---->>
先理清思路,然后就好写了;
从前端开始倒推,然后开始完善我们需要的一些代码!!
前端------>>>jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>注册页面</title>
<script src="static/js/jquery.js"></script>
<script>
var xhr;
function checkName() {
var str = $("#uName").val();/*获取input中输入的文字*/
/*当str为null或者空格字符串的时候*/
if (str == null || str == "") {
$("#checkInfo").html("<font color='red'> 用户名不允许为空</font>");
/* 如果不符合条件则不执行下面的内容;*/
return;
}
//如果不为空则显示字符 ''
$("#checkInfo").text('');
//接下来发送异步请求
xhr = new XMLHttpRequest();
//怎么发送呢?指定发送方式,发送地址,是否异步---true
xhr.open("GET", "CheckName.do?userName="+$("#uName").val(),true)
// 设置回调函数,用于接好服务器端发送过来的信息
xhr.onreadystatechange = showReturnInfo;
//正式发送
xhr.send(null);
}
function showReturnInfo() {
/* 如果进行到第四阶段了,xhr的状态为200*/
if (xhr.readyState == 4 && xhr.status == 200) {
//获得服务器返回的数据
var returnInfo = xhr.responseText;
console.log(returnInfo);
if (returnInfo == '用户名可用') {
$("#checkInfo").html("<font color='green'>用户名可用</font>");
} else {
$("#checkInfo").html("<font color='red'>用户名不可用</font>");
}
}
}
</script>
</head>
<body>
<form method="get" action="MyServlet01.do">
账号: <input type="text" name="userName" id="uName" onblur="checkName()"><span id="checkInfo"></span><br>
密码:<input type="password" name="userPwd" id="uPwd"><br>
<input type="submit" value="注册">
</form>
</body>
</html>
针对前端3处,
准备一个接口和实现类专门用以从数据库查询数据,并返回信息;
public class CheckUserImp extends BaseDao implements Check {
@Override
public List CheckUser(String uName, String uPwd) {
String sql = "select * from userinfo where userName = ? and userPwd = ? ; ";
List list = baseQuery(User.class, sql, uName, uPwd);
return list;
}
@Override
public String RemindInfo(String uName) {
String sql = "select * from userinfo where userName = ? ;";
List list = baseQuery(User.class, sql,uName);
if (null != list&&list.size()!=0) {
return "用户名不可用";
}
return "用户名可用";
}
}
封装的实体类
准备servlet,用以检查用户名并向前端发送信息-----(异步)
import AJAXDao.Check;
import AJAXDao.CheckImp.CheckUserImp;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/CheckName.do")
public class CheckName extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
String userName = req.getParameter("userName");
Check check = new CheckUserImp();
String remindInfo = check.RemindInfo(userName);
resp.setCharacterEncoding("UTF-8");
resp.setContentType("text/html;charset=UTF-8");
resp.getWriter().write(remindInfo);
}
}
JSON(JavaScriptObject Notation, JS 对象简谱) 是一种轻量级的数据交换格式。它基于ECMAScript (欧洲计算机协会制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。它有如下优点
1 轻量级,实现数据转换
2 Json 格式既能考虑到前端对象的特点 同时也能兼顾后台对象信息的特点
3 Json 格式可以被前端直接识别并解析成对象
4 jQuery形式实现AJAX默认前后端传递数据的格式就是JSON
json在前端中的应用;
<script>
// 用json创建对象
var person = {"name": "张三", "age": 20}
console.log(person);
console.log(person.name +"--"+person.age);
var persons =[{"name":"李四","age":45,"gender":"女"},{'name':"王五","age":22}];
console.log(persons);
for (var i = 0; i < persons.length; i++) {
var per=persons[i];
console.log(per.name+"----"+per.age);
}
/*字符串信息*/
var personStr='{"name":"gavin","age":18,"gender":"男"}';
/*将上面的信息转换成对象*/
var cha=JSON.parse(personStr);
console.log(cha);
console.log(cha.name+"---"+cha.age+"---"+cha.gender);
json的应用---->>
准备一个servlet用于向前端发送信息----
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import pojo.Personn;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
@WebServlet("/Myservlet01.do")
public class Myservlet01 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
Personn per= new Personn("张三",21,"男",new Date());
Personn per1= new Personn("李四",18,"男",new Date());
Personn per2= new Personn("王五",22,"男",new Date());
Personn per3= new Personn("赵六",26,"男",new Date());
Personn per4= new Personn("陆七",19,"男",new Date());
List<Personn> list= new ArrayList<>();
Collections.addAll(list,per,per1,per2,per3,per4);
//设置一些格式
// GsonBuilder 用于指定字符串内某些数据类型的格式
GsonBuilder gsonBuilder=new GsonBuilder().setDateFormat("yyyy-MM-dd");
//指定好之后创建gson对象
Gson gson=gsonBuilder.create();
// String toJson = gson.toJson(per);
String toJson = gson.toJson(list);//此时i是一个Json对象集合
System.out.println(toJson);
resp.getWriter().write(toJson);
}
}
准备前端页面–>>
<%--
Created by IntelliJ IDEA.
User: Gavin
Date: 2021/11/5
Time: 10:44
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<script src="js/jquery.js"></script>
<script>
var xhr;
function checkN() {
var str = $("#u_Name").val();
if (str == null || str == "") {
$("#remindInfo").text("用户名不允许为空");
return;
}
$("#remindInfo").text('');
xhr = new XMLHttpRequest();
xhr.open("GET", "Myservlet01.do?userName=" + str, true);
xhr.send(null);
xhr.onreadystatechange = showReturnInfo;
}
function showReturnInfo() {
if (xhr.status == 200 && xhr.readyState == 4) {
//根据需要看怎样处理
var info = xhr.responseText;//这里得到一个字符串--是json格式的对象集合
var Inform = JSON.parse(info);/*将字符串转为对象集合*/
for (var i = 0; i < Inform.length; i++) {
var per=Inform[i];
console.log(per.u_name);
console.log(per.u_age);
console.log(per.u_gender);
console.log(per.u_birthday);
}
}
}
</script>
<form method="get" action="">
<input type="text" name="userName" id="u_Name" placeholder="请输入账号" onblur="checkN()"><span
id="remindInfo"></span><br>
<input type="password" name="userPwd" id="u_Pwd"><br>
<input type="submit" value="注册">
</form>
</body>
</html>
AJAX结合jquery简化异步交互代码---->>
<!DOCTYPE html>
<html lang="en">
<meta charset="UTF-8"/>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<script src="js/jquery.js"></script>
<script>
// // 用json创建对象
// var person = {"name": "张三", "age": 20}
// console.log(person);
// console.log(person.name + "--" + person.age);
// var persons = [{"name": "李四", "age": 45, "gender": "女"}, {'name': "王五", "age": 22}];
// console.log(persons);
// for (var i = 0; i < persons.length; i++) {
// var per = persons[i];
// console.log(per.name + "----" + per.age);
// }
//
// var personStr = '{"name":"gavin","age":18,"gender":"男"}';
// /*将上面的信息转换成对象*/
// var cha = JSON.parse(personStr);
//
//
// console.log(cha);
// console.log(cha.name + "---" + cha.age + "---" + cha.gender);
var xhr;
function CheckName() {
var u_name = $("#u_Name").val();
if (u_name == null || u_name == "") {
$("#checkInfo").text("用户名不允许为空");
return;
}
$("#checkInfo").text("");
//通过jquery封装好的ajax()来发送异步请求
/* $.ajax(属性名:属性值,方法名:方法)*/
$.ajax(
{
type: "GET",//请求方式
url: "CheckDemoImp.do?",//后台服务路径
data: "userName=" + $("#u_Name").val(),//提交的数据
success: function (info) {//成功时候响应
$("#checkInfo").text(info);
},
error: function () {//出现错误时候响应
}
}
);
// xhr = new XMLHttpRequest();
// xhr.open("GET", "CheckDemoImp.do?userName=" + u_name, true);
// xhr.send(null);
// xhr.onreadystatechange = remindInfo;
}
// function remindInfo() {
// if (xhr.status == 200 && xhr.readyState == 4) {
// var Info = xhr.responseText;
// $("#checkInfo").text(Info);
// }
//}
</script>
<form method="get" action="myServlet.do">
<input type="text" id="u_Name" placeholder="用户名" name="userName" onblur="CheckName()"> <span
id="checkInfo"></span><br>
<input type="password" id="u_Pwd" placeholder="密码" name="userPwd"><br>
<input type="submit" value="注册">
</form>
</body>
</html>
jquery中封装了ajax函数,通过主函数去直接调用就可以了,主义的就是参数的写法,这个跟ajax的open方法参数基本一样的理解----
{
type:“请求方式”,
url:“将要发送到的服务端servlet”,
data:“要发送的数据”,
success: function(参数){
放一些响应成功后的信息;
},
error:function(参数){
产生异常时响应什么内容;
}
}
每个属性之间有用 逗号来区分;
ajax发送给后端的数据格式------>>
后端发送数据,格式为JSON,前端解析json
准备一个jsp或者html,
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>注册页面</title>
</head>
<body>
<script src="js/jquery.js"></script>
<script>
function Info() {
$.ajax(
{
type: "GET",
url: "AjaxTest.do?",
//data:{"userName":"小明","password":"123456"},可以在属性名处加引号也可以不加
data: {userName: "小明", password: "123456"},//json对象的形式
//data:"{\"userName\":\"小明\",\"password\":\"123456\"}",//json字符串形式
dataType: "json",//以json来解析后端发过来的数据
success: function (info) {
//如果后端发送过来的是字符串 ---info
alert(info);//是一个json对象
console.log(info);
console.log(info.userName);
console.log(info.password);
/* var per = JSON.parse(info);
console.log(per.userName);
console.log(per.password);*/
},
error: function () {
}
}
)
}
</script>
<%--异步请求--%>
<input type="button" value="点我呀!!" onclick="Info()">
</body>
</html>
后端代码,准备一个servlet
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/AjaxTest.do")
public class AjaxTest extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
resp.setContentType("text/html;charset=UTF-8");
String userName = req.getParameter("userName");
String password = req.getParameter("password");
if("小明".equals(userName)&&"123456".equals(password)){
String str="{\"userName\":\"小明\",\"password\":\"123456\"}";//json 对象的形式
resp.getWriter().write(str);
}
}
}
前端解析---->>>
如果去掉dataType属性----->>>
怎么办呢?
手动转换为json格式的对象
@WebServlet("/AjaxTest.do")
public class AjaxTest extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
resp.setContentType("text/html;charset=UTF-8");
String userName = req.getParameter("userName");
String password = req.getParameter("password");
List<Personn> list = new ArrayList<>();
Personn per= new Personn("张三",21,"男",new Date());
Personn per1= new Personn("李四",18,"男",new Date());
Personn per2= new Personn("王五",22,"男",new Date());
Personn per3= new Personn("赵六",26,"男",new Date());
Personn per4= new Personn("陆七",19,"男",new Date());
Collections.addAll(list,per,per1,per2,per3,per4);
if("小明".equals(userName)&&"123456".equals(password)){
//String str="{\"userName\":\"小明\",\"password\":\"123456\"}";//json对象的形式
//String str="{userName:\"小明\",password:\"123456\"}";//json对象的形式
//将集合发送到前端,由于有日期需要处理的格式
GsonBuilder gsonBuilder=new GsonBuilder();//不处理日期格式
// GsonBuilder gsonBuilder=new GsonBuilder().setDateFormat("yyyy-MM-dd");
//GsonBuilder gsonBuilder1 = gsonBuilder.setDateFormat("yyyy-MM-dd");
Gson gson = gsonBuilder.create();
String json = gson.toJson(list);
resp.getWriter().write(json);
}
}
}
向前端发送集合后解析
jQuery.ajax()属性详解
1.url:
要求为String类型的参数,(默认为当前页地址)发送请求的地址。
2.type:
要求为String类型的参数,请求方式(post或get)默认为get。注意其他http请求方法,例如put和delete也可以使用,但仅部分浏览器支持。
3.timeout:
要求为Number类型的参数,设置请求超时时间(毫秒)。此设置将覆盖$.ajaxSetup()方法的全局设置。
4.async:
要求为Boolean类型的参数,默认设置为true,所有请求均为异步请求。如果需要发送同步请求,请将此选项设置为false。注意,同步请求将锁住浏览器,用户其他操作必须等待请求完成才可以执行。
5.cache:
要求为Boolean类型的参数,默认为true(当dataType为script时,默认为false),设置为false将不会从浏览器缓存中加载请求信息。
6.data:
要求为Object或String类型的参数,发送到服务器的数据。如果已经不是字符串,将自动转换为字符串格式。get请求中将附加在url后。防止这种自动转换,可以查看 processData选项。对象必须为key/value格式,例如{foo1:“bar1”,foo2:“bar2”}转换为&foo1=bar1&foo2=bar2。如果是数组,JQuery将自动为不同值对应同一个名称。例如{foo:[“bar1”,“bar2”]}转换为&foo=bar1&foo=bar2。
7.dataType:
要求为String类型的参数,预期服务器返回的数据类型。如果不指定,JQuery将自动根据http包mime信息返回responseXML或responseText,并作为回调函数参数传递。可用的类型如下:
xml:返回XML文档,可用JQuery处理。
html:返回纯文本HTML信息;包含的script标签会在插入DOM时执行。
script:返回纯文本JavaScript代码。不会自动缓存结果。除非设置了cache参数。注意在远程请求时(不在同一个域下),所有post请求都将转为get请求。
json:返回JSON数据。
**jsonp:JSONP格式。**使用JSONP形式调用函数时,例如myurl?callback=?,JQuery将自动替换后一个“?”为正确的函数名,以执行回调函数。
text:返回纯文本字符串。
8.beforeSend:
要求为Function类型的参数,发送请求前可以修改XMLHttpRequest对象的函数,例如添加自定义HTTP头。在beforeSend中如果返回false可以取消本次ajax请求。
XMLHttpRequest对象是惟一的参数。
function(XMLHttpRequest){
this; //调用本次ajax请求时传递的options参数
}
9.complete:
要求为Function类型的参数,请求完成后调用的回调函数(请求成功或失败时均调用)。参数:XMLHttpRequest对象和一个描述成功请求类型的字符串。
function(XMLHttpRequest, textStatus){
this; //调用本次ajax请求时传递的options参数
}
10.success:
要求为Function类型的参数,请求成功后调用的回调函数,有两个参数。
(1)由服务器返回,并根据dataType参数进行处理后的数据。
(2)描述状态的字符串。
function(data, textStatus){
//data可能是xmlDoc、jsonObj、html、text等等
this; //调用本次ajax请求时传递的options参数
}
常用的属性:
$.ajax(
{
type: "GET",
url: "AjaxTest.do?",
async: true,//以异步的i形式发送,默认也是
//data:{"userName":"小明","password":"123456"},可以在属性名处加引号也可以不加
data: {userName: "小明", password: "123456"},//json对象的形式
//data:"{\"userName\":\"小明\",\"password\":\"123456\"}",//json字符串形式
// dataType: "json",//以json来解析后端发过来的数据
success: function (info) {
// 发过来的是集合
alert(info);
var t = JSON.parse(info);
alert(t);//是一个json对象
for (var i = 0; i < t.length; i++) {
var per = t[i];
console.log(per);
}
$.each(t, function (i, e) {//i为下标,e为元素
console.log(e);
})
},
error: function () {
},
beforeSend: function (xhr) {
//在请求之前做一些处理
//return false;//取消ajax请求
},
complete: function () {
alert('请求完成,成不成功都会执行');
},
cache: true,//启用缓存
//内容编码类型默认为"application/x-www-form-urlencoded"。该默认值适合大多数应用场合。
contentType: "application/x-www-form-urlencoded",//
processData: true,//是否自动转换信息
dataFilter: function (data, type) {
/*
* 数据过滤方法
* 给Ajax返回的原始数据进行预处理的函数。
* 提供data和type两个参数。
* data是Ajax返回的原始数据,
* type是调用jQuery.ajax时提供的dataType参数。
* 函数返回的值将由jQuery进一步处理
* */
}
}
)
还有简化的一些方法可以使用,在jquery中你会发现一些神奇的API,大大简化我们的代码量,
一起瞅瞅,jQuery中封装好的API
第一种是经典形式,前面已经用到过,不在赘述;
load(url, [data], [callback])
准备一个servlet
准备一个jsp或者html,用load方法去实现异步交互
大大减少了代码量;
除此之外load方法还可以加载一些其他元素
比如下面的代码
<%--
Created by IntelliJ IDEA.
User: Gavin
Date: 2021/11/6
Time: 10:13
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<script src="js/jquery.js"></script>
<style type="text/css">
#d1 {
border: 1px solid red;
width: 200px;
height:300px;
}
</style>
<script>
function showInput() {
// $("#d1").load("ajaxload.do?", "userInput=" + $("#uInput").val(), function () {
//alert("响应结束");
// })
// $("#d1").load( "staticIndex.html #fm")
//$("#d1").load("staticIndex.html")//可以是整个页面,也可以是页面中的元素
$("#d1").load("index.jsp")//可以是jsp
}
</script>
<div id="d1"></div>
<input type="text" name="userInput" id="uInput" placeholder="请输入内容" onblur="showInput()">
</body>
</html>
应用-------注册页面可以用load实现.
jQuery.get(url, [data], [callback], [type])
通过远程 HTTP GET 请求载入信息。
这是一个简单的 GET 请求功能以取代复杂 $.ajax 。请求成功时可调用回调函数。如果需要在出错时执行函数,请使用 $.ajax。
url,[data,[callback]]String,Map/String,CallbackV1.0url:待装入 HTML 网页网址。
data:发送至服务器的 key/value 数据。在jQuery 1.3中也可以接受一个字符串了。
callback:载入成功时回调函数。
$.get(
"ajaxload.do?",
"userInput=" + $("#uInput").val(),
function(info){
$("#d1").html(info)
}
)
post(url, [data], [callback], [type])
通过远程 HTTP POST 请求载入信息。
这是一个简单的 POST 请求功能以取代复杂 $.ajax 。请求成功时可调用回调函数。如果需要在出错时执行函数,请使用 $.ajax。
$.post(
"ajaxload.do?",
"userInput=" + $("#uInput").val(),
function(info){
$("#d1").html(info)
}
)
如果传过来的是对象或者其他引用
getJSON(url, [data], [callback])
通过 HTTP GET 请求载入 JSON 数据。
在 jQuery 1.2 中,您可以通过使用JSONP形式的回调函数来加载其他网域的JSON数据,如 “myurl?callback=?”。jQuery 将自动替换 ? 为正确的函数名,以执行回调函数。 注意:此行以后的代码将在这个回调函数执行前执行。
$.getJSON(
"ajaxload.do?",
"userInput=" + $("#uInput").val(),
function (info) {
//遍历集合
$.each(info,function (i, e) {
console.log(e)
})
}
)
常用的jquery异步请求方法就这几个,
$.ajax()—经典方法
$.post()
$.get()
$.getJson()----这种方法默认是get方法请求,然后转换成json
ajax跨域请求
跨域—是指页面请求的资源不在同一个服务器上,怎么模拟呢???
首先打开Hbuilder,新建一个项目
index页面内容---->>>直接从idea中拷贝
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<script src="js/jquery.js"></script>
<script>
var xhr;
function CheckUserName() {
if ($("#uname1").val() == null || $("#uname1").val() == '') {
$("#Info").html("<font color='red'>用户名不能为空</font>");
return;
}
$("#Info").text('');
$.get(
"checkNameServlet.do?",
userName = +$("#uname1").val(),
function (info) {
if (info == "用户名可用") {
$("#Info").html("<font color='green'>用户名可用</font>");
} else {
$("#Info").html("<font color='red'>用户名已被占用</font>");
}
}
)
}
</script>
<form method="post" action="MyServlet01.do">
<input type="text" id="uname1" name="userName" placeholder="账户" onblur="CheckUserName()"><span id="Info"></span>
<br>
<input type="password" name="userPwd" placeholder="密码">
<br>
<input type="submit" value="提交">
</form>
</body>
</html>
效果并没有达到,
查看一下
发现Hbuilder在请求servlet.do是直接在本项目下请求的,现在是模拟跨域请求,即我们的html上的url是相对路径,改为绝对路径再次请求-----
仍然没有达到效果,再看一下原因------>>被拦截了
如何实现AJAX跨域
为什么会出现上面的问题?
那就要了解什么是跨域?
出于浏览器的同源策略限制。同源策略(Sameoriginpolicy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。同源策略会阻止一个域的javascript脚本和另外一个域的内容进行交互。所谓同源(即指在同一个域)就是两个页面具有相同的协议(protocol),主机(host)和端口号(port)
我们分析一下,
因为要跨域请求一个servlet,那是这个请求是在哪里产生的呢?
jquery中封装的函数,那可不可以跨域请求一个jquery文件来实现异步请求呢?
首先打开IDEA中的项目,
运行项目,然后在浏览器中打开该jquery文件,
复制浏览器中的地址到 Hbuilder中的index.html文件中
再次运行,发现仍然不能完成异步请求;
我们来测试下注掉异步请求的部分代码,然后再尝试一下,发现验证用户名不为空部分是好使的,说明可以跨域请求js文件,但是直接异步请求跨域的servlet却不可以;
接下来我们在post的方法中加入一个属性----->>>
那么这样可不可以成功的异步请求到servlet呢?
如何证明呢?我们在servlet中输出一下
在浏览器中输入文字,servlet成功接收到了信息,说明的确实现了跨域请求,但是返回的数据浏览器中报错 —>Uncaught ReferenceError: 用户名可用 is not defined 说明是返回的数据解析式出现了问题;
为什么加了属性 jsonp就可以实现跨域异步请求呢?
原理是这样子的,通过增加type属性 "jsonp"会创建一个script,里面的url指向这个servlet,即相当于这个样子的----->>
<script src= "http://localhost:8080/AJAXproject_war_exploded/checkNameServlet.do?"></script>
然后返回的数据会被浏览器当作js代码来运行,
为便于测试,修改servlet中返回的数据------
重新部署项目,
这说明后台servlet返回的数据确实是被浏览器当做js代码来运行的;
既然是这样,那就好办了,
告诉浏览器去调用某个js方法
这样不就可以实现我们想要的效果了么,
重新部署项目,
但是我们一般是后台代码写好后不会怎么轻易修改,因为修改后需要重新部署或者重启服务器,那么怎么解决呢?
在前端请求时的参数中加入回调时的js方法,这样后端获取该方法名然后拼接到返回数据中就可以了;
仍然是好使的;,但是这种方法是使得原来post/get中的function失效了;因为post/get方法参数类型可选的比较少,
url(必选), [data], [callback], [type]),并没有jsonp可选,
如果想要使得方法中的function不失效,可以选择用更加详细的$.ajax()来实现,(.ajax()可以实现全局的属性设置,用于处理比较复杂一些的异步请求)
如果用ajax方法实现------>>
$.ajax({
type: "POST",
url: "http://localhost:8080/AJAXproject_war_exploded/checkNameServlet.do?",
data: "userName=" + $("#uname1").val(),
dataType: "jsonp",
jsonp:"method",//命名success属性下的方法名
success: function(info) {
if(info == "用户名可用") {
$("#Info").html("<font color='green'>用户名可用</font>");
} else {
$("#Info").html("<font color='red'>用户名已被占用</font>");
}
}
})
jsonp属性的作用:
在一个jsonp请求中重写回调函数的名字。这个值用来替代在"callback=?"这种GET或POST请求中URL参数里的"callback"部分,比如{jsonp:‘onJsonPLoad’}会导致将"onJsonPLoad=?"传给服务器。
后端代码----->>>
这种相当于在data种拼接了一个"&method=系统生成的名字",
打印的回调函数名----->>>
总结,在异步请求时,post或者get方法实现时 增加一个属性 type, 为 “jsonp”,但是post/get中的function(){}就失效了
如果是ajax方法实现,需要增加 dataType=“jsonp”,想要使得方法内部的function(){} 有效并得以执行,还需要加一个参数 jsonp:“方法名”
针对上面的post/get方法在实现跨域时,function()会失效,可以通过jquery中封装好的getjson方法------->>>
getJSON(url, [data], [callback])
通过 HTTP GET 请求载入 JSON 数据。
在 jQuery 1.2 中,您可以通过使用JSONP形式的回调函数来加载其他网域的JSON数据,如 “myurl?callback=?”。jQuery 将自动替换 ? 为正确的函数名,以执行回调函数。 注意:此行以后的代码将在这个回调函数执行前执行。
参数
url,[data],[callback]
url:发送请求地址。
data:待发送 Key/value 参数。
callback:载入成功时回调函数。
$.getJSON(
"http://localhost:8080/AJAXproject_war_exploded/checkNameServlet.do?callback=?",
"userName=" + $("#uname1").val(),
function(info) {
if(info == "用户名可用") {
$("#Info").html("<font color='green'>用户名可用</font>");
} else {
$("#Info").html("<font color='red'>用户名已被占用</font>");
}
}
)
url上加上—任意名 =?,