异步请求-AJAX

news/2024/5/9 2:48:28/文章来源:https://blog.csdn.net/listeningdu/article/details/128061298

什么是同步交互

首先用户向HTTP服务器提交一个处理请求。接着服务器端接收到请求后,按照预先编写好的程序中的业务逻辑进行处理,比如和数据库服务器进行数据信息交换。最后,服务器对请求进行响应,将结果返回给客户端,返回一个HTML在浏览器中显示,通常会有CSS样式丰富页面的显示效果。

 

 

优点

可以保留浏览器后退按钮的正常功能。在动态更新页面的情况下,用户可以回到前一个页面状态,浏览器能记下历史记录中的静态页面,用户通常都希望单击后退按钮时,就能够取消他们的前一次操作,同步交互可以实现这个需求.

缺点

1同步交互的不足之处,会给用户一种不连贯的体验,当服务器处理请求时,用户只能等待状态,页面中的显示内容只能是空白。

2因为已经跳转到新的页面,原本在页面上的信息无法保存,好多信息需要重新填写

什么是异步交互

指发送一个请求,不需要等待返回,随时可以再发送下一个请求,即不需要等待。在部分情况下,我们的项目开发中都会优先选择不需要等待的异步交互方式。将用户请求放入消息队列,并反馈给用户,系统迁移程序已经启动,你可以关闭浏览器了。然后程序再慢慢地去写入数据库去。这就是异步。异步不用等所有操作等做完,就响应用户请求。即先响应用户请求,然后慢慢去写数据库,用户体验较好

 

优点

1前端用户操作和后台服务器运算可以同时进行,可以充分利用用户操作的间隔时间完成运算

2页面没有跳转,响应回来的数据直接就在原页面上,页面原有信息得以保留

缺点

可能破坏浏览器后退按钮的正常行为。在动态更新页面的情况下,用户无法回到前一个页面状态,这是因为浏览器仅能记录的始终是当前一个的静态页面。用户通常都希望单击后退按钮,就能够取消他们的前一次操作,但是在AJAX这样异步的程序,却无法这样做。

 1.AJAX介绍

AJAX 即

“Asynchronous Javascript And XML”(异步 JavaScript和 XML),是指一种创建交互式、快速动态网页应用的网页开发技术,无需重新加载整个网页的情况下,能够更新部分网页的技术。通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。

AJAX关键技术

  • 使用CSS构建用户界面样式,负责页面排版和美工
  • 使用DOM进行动态显示和交互,对页面进行局部修改
  • 使用XMLHttpRequest异步获取数据
  • 使用JavaScript将所有的元素绑定在一起

 AJAX的最大的特点: 异步访问,局部刷新

AJAX之验证用户名是否被占用

 JS表单验证只能校验格式是否正确,但是无法验证用户名是否已经存在,这个就需要后台程序接受到数据后通过查询才能够完成的,那么这里就非常适用于使用异步方式校验,保证用于数据提交后,业务完成的成功率.提升用于体验感

代码示例:

jsp代码

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html><head><title>$Title%sSourceCode%lt;/title><script>var xhr ;function checkUname(){// 获取输入框中的内容var unameDOM=document.getElementById("unameI");var unameText =unameDOM.value;var unameInfoDom =document.getElementById("unameInfo");if(null == unameText || unameText == ''){unameInfoDom.innerText="用户名不能为空";return;}unameInfoDom.innerText="";// 发送异步请求// 获取一个 XMLHttpRequest对象 ,对象可以帮助我们发送异步请求xhr =new XMLHttpRequest();// 使用xhr对象设置打开链接,设置请求方式和参数xhr.open("请求方式","请求的URL",是否使用异步方式);xhr.open("GET","unameCheckServlet.do?uname="+unameText,true);// 设置回调函数xhr.onreadystatechange=showReturnInfo;// 正式发送请求xhr.send(null);}function showReturnInfo(){if(xhr.readyState==4 && xhr.status==200){var returnInfo =xhr.responseText;var unameInfoDom =document.getElementById("unameInfo");unameInfoDom.innerText=returnInfo;}}</script></head><body><form action="myServlet1.do" >用户名:<input id="unameI" type="text" name="uname" onblur="checkUname()"><span id="unameInfo" style="color: red"></span><br/>密码:<input type="password" name="pwd"><br/><input type="submit"></form></body>
</html>

servlet代码

package com.msb.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;
/*** @Author: Ma HaiYang* @Description: MircoMessage:Mark_7001*/
@WebServlet("/unameCheckServlet.do")
public class UnameCheckServlet extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String uname = req.getParameter("uname");String info="";if("msb".equals(uname)){info="用户名已经占用";}else{info="用户名可用";}// 向浏览器响应数据resp.setCharacterEncoding("UTF-8");resp.setContentType("text/html;charset=UTF-8");resp.getWriter().print(info);}
}

AJAX异步提交请求的步骤为

1 获取XMLHTTPRequest对象xhr=new XMLHttpRequest();

2打开链接xhr.open("GET","loginServlet?uname="+uname,true);

3设置回调函数xhr.onreadystatechange=showRnturnInfo;

4提交数据  xhr.send(data)

目前存在的问题

原生js提交AJAX异步请求代码比较繁琐,处理复杂数据比较麻烦,后续可以使用jQuery解决

2.AJAX配合JQuery实现异步请求 

每次书写AJAX代码比较繁琐 步骤都是一样的,数据回显使用原生js代码也比较繁琐,可以使用jQuery对上述问题进行优化,jQuery不仅仅对dom操作进行了封装 同时也对AJAX提交和回显已经进行了封装,可大大简化AJAX的操作步骤

jQuery.ajax()的简单使用

基本语法为(经典语法):

前端代码

<html>
<head><title>$Title%sSourceCode%lt;/title><meta charset="UTF-8"/><script src="js/jquery.min.js"></script><script>function checkUname(){// 获取输入框中的内容if(null == $("#unameI").val() || '' == $("#unameI").val()){$("#unameInfo").text("用户名不能为空");return;}$("#unameInfo").text("");// 通过jQuery.ajax() 发送异步请求$.ajax({type:"GET",// 请求的方式 GET  POSTurl:"unameCheckServlet.do?", // 请求的后台服务的路径data:"uname="+$("#unameI").val(),// 提交的参数success:function(info){ // 响应成功执行的函数$("#unameInfo").text(info)}})}</script>
</head>
<body>
<form action="myServlet1.do" >用户名:<input id="unameI" type="text" name="uname" onblur="checkUname()"><span id="unameInfo" style="color: red"></span><br/>密码:<input type="password" name="pwd"><br/><input type="submit" value="提交按钮">
</form>
</body>
</html>

 后台代码

package com.msb.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;
/*** @Author: Ma HaiYang* @Description: MircoMessage:Mark_7001*/
@WebServlet("/unameCheckServlet.do")
public class UnameCheckServlet extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String uname = req.getParameter("uname");String info="";if("msb".equals(uname)){info="用户名已经占用";}else{info="用户名可用";}// 向浏览器响应数据resp.setCharacterEncoding("UTF-8");resp.setContentType("text/html;charset=UTF-8");resp.getWriter().print(info);}
}

JSON格式处理

前端代码

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script src="js/jquery.min.js"></script><script>function testAjax(){// 向后台发送一个ajax异步请求// 接收响应的数据$.ajax({type:"GET",url:"servlet1.do",data:{"username":"zhangsan","password":"123456"},// key=value&key=value  {"属性名":"属性值"}dataType:"json",//以什么格式接收后端响应给我们的信息success:function(list){$.each(list,function(i,e){console.log(e)})}})}</script>
</head>
<body>
<input type="button" value="测试" onclick="testAjax()">
</body>
</html>

 

package com.msb.servlet;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.msb.pojo.Student;
import sun.util.calendar.LocalGregorianCalendar;
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;
/*** @Author: Ma HaiYang* @Description: MircoMessage:Mark_7001*/
@WebServlet("/servlet1.do")
public class Servlet1 extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String username = req.getParameter("username");String password = req.getParameter("password");System.out.println(username);System.out.println(password);Student stu1=new Student("小黑","男",10,new Date());Student stu2=new Student("小白","男",10,new Date());Student stu3=new Student("小黄","男",10,new Date());Student stu4=new Student("小花","男",10,new Date());ArrayList<Student> list =new ArrayList<>();Collections.addAll(list,stu1,stu2,stu3,stu4);GsonBuilder gb =new GsonBuilder();gb.setDateFormat("yyyy-MM-dd");Gson gson = gb.create();String json = gson.toJson(list);resp.setContentType("text/html;charset=UTF-8");resp.setCharacterEncoding("UTF-8");resp.getWriter().print(json);}
}

 jQuery.ajax()属性详解

$.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参数}

10.success:

要求为Function类型的参数,请求成功后调用的回调函数,有两个参数。
(1)由服务器返回,并根据dataType参数进行处理后的数据。
(2)描述状态的字符串。 
 

function(data, textStatus){//data可能是xmlDoc、jsonObj、html、text等等this; //调用本次ajax请求时传递的options参数}


11.error:

要求为Function类型的参数,请求失败时被调用的函数。该函数有3个参数,即XMLHttpRequest对象、错误信息、捕获的错误对象(可选)。ajax事件函数如下: 
 

function(XMLHttpRequest, textStatus, errorThrown){//通常情况下textStatus和errorThrown只有其中一个包含信息this; //调用本次ajax请求时传递的options参数}

 
12.contentType:

要求为String类型的参数,当发送信息至服务器时,内容编码类型默认为"application/x-www-form-urlencoded"。该默认值适合大多数应用场合。

13.dataFilter:

要求为Function类型的参数,给Ajax返回的原始数据进行预处理的函数。提供data和type两个参数。data是Ajax返回的原始数据,type是调用jQuery.ajax时提供的dataType参数。函数返回的值将由jQuery进一步处理。

 function(data, type){//返回处理后的数据return data;}

 
14.global:

要求为Boolean类型的参数,默认为true。表示是否触发全局ajax事件。设置为false将不会触发全局ajax事件,ajaxStart或ajaxStop可用于控制各种ajax事件。

15.ifModified:

要求为Boolean类型的参数,默认为false。仅在服务器数据改变时获取新数据。服务器数据改变判断的依据是Last-Modified头信息。默认值是false,即忽略头信息。

16.jsonp:

要求为String类型的参数,在一个jsonp请求中重写回调函数的名字。该值用来替代在"callback=?"这种GET或POST请求中URL参数里的"callback"部分,例如{jsonp:'onJsonPLoad'}会导致将"onJsonPLoad=?"传给服务器。

17.username:

要求为String类型的参数,用于响应HTTP访问认证请求的用户名。

18.password:

要求为String类型的参数,用于响应HTTP访问认证请求的密码。

19.processData:

要求为Boolean类型的参数,默认为true。默认情况下,发送的数据将被转换为对象(从技术角度来讲并非字符串)以配合默认内容类型"application/x-www-form-urlencoded"。如果要发送DOM树信息或者其他不希望转换的信息,请设置为false。

20.scriptCharset:

要求为String类型的参数,只有当请求时dataType为"jsonp"或者"script",并且type是GET时才会用于强制修改字符集(charset)。通常在本地和远程的内容编码不同时使用。

 一个ajax方法中,可用的属性和方法大致如下

<script>function testAjax(){$.ajax({url:"servlet1",/*post get  部分浏览器可使用put delete*/type:"get",/*请求超时的时间设置*/timeout:2000,/*是否发送异步请求,默认值为true,如需同步请求,改为false*/async:true,/*是否从浏览器的缓存中加载信息,默认为true,false则不读取浏览器缓存*/cache:true,/*向服务器发送的数据,可以是key/value格式,也可以是对象格式* get方式下,会将信息附加在url后,如果数据不是字符串,会转换成字符串格式* */data:{username:"bjmsb",password:"bjmsb"},/** 默认值为true 默认情况下,发送的数据将被转换为对象以配合*   content-type:application/x-www-form-urlencoded* 如果发送信息不希望被转换,设置为false即可* */proccessData:true,/*发送到服务器的数据为String类型时,默认值为*   application/x-www-form-urlencoded* 该值适合大多数应用场景* */contentType:"application/x-www-form-urlencoded",/** 预期服务器返回值类型,* 如果不指定 jQuery根据http响应mime信息返回xml或者text* 并作为返回值传递,可选类型如下* xml 返回xml数据(基本淘汰)* html:返回纯文本HTML信息* script:返回JS脚本,* json:返回json数据* jsonp:jsonp格式* text:返回纯文本,也是默认格式* */dataType:"json",/** 指定跨域回调函数名* *///jsonp:"fun1",/*只有当请求参数为dataType为jsonp或者script,并且是get方式请求时* 才能强制修改字符集,通常在跨域编码不同时使用* *///  scriptCharset:"utf-8",beforeSend:function(XMLHttpRequest){/** 请求发送前可以通过该方法修改XMLHttpRequest对象函数* 如听见请求头* 如果该方法返回false,则会取消ajax请求* */},success:function(data,textStatus){/**一般请求成功后会调用的函数,有两个可选参数* data,数据 根据dataType的配置处理之后的数据 可能是xml text json 等* testStatus ,描述响应状态的字符串*  */},error:function(XMLHttpRequest,textStatus,errorThrown){/** 请求失败时调用的函数,可选参数有* XMLHttpRequest对象* 错误信息* 捕获的异常对象* */},complete:function(XMLHttpRequest,textStatus){/** 无论请求是否成功都睡调用的回调函数* 可选参数有* XMLHttpRequest对象* textStatus 描述成功请求的类型的字符串* */},dataFilter:function(data,type){/** 数据过滤方法* 给Ajax返回的原始数据进行预处理的函数。* 提供data和type两个参数。* data是Ajax返回的原始数据,* type是调用jQuery.ajax时提供的dataType参数。* 函数返回的值将由jQuery进一步处理* */}})}</script>

注意:

ajax异步提交的可选属性和方法较多,实际研发我们没必要写这么多,一般可以使用默认值的属性就可以省略不写,一些业务逻辑或者功能上不需要的方法也可以省略不写,由于属性太多,针对于一些特殊情况,jQuery也给我们提供了一些专用的方法,这样可以简化$.ajax的写法,每一种简化写法都相当于已经指定了$.ajax一些属性的值.

jQuery实现AJAX的其他写法

4.3.1 $.load()

jQuery load() 方法是简单但强大的 AJAX 方法,load() 方法从服务器加载数据,并把返回的数据放入被选元素中。默认使用 GET 方式 - 传递附加参数时自动转换为 POST 方式,

语法为:$(selector).load(URL,data,callback);

  参数的含义为: 

  • url: URL地址
  • data:待发送参数。 
  • callback:载入成功时回调函数。

测试代码

准备第一个页面

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script src="js/jquery.min.js"></script><script>function testLoad(){//$("#d1").load("servlet2.do","username=aaa&password=bbb",function(){alert("响应结束")})$("#d1").load("loadPage.html #a")}</script>
</head>
<body>
<div id="d1" style="width: 100px;height: 100px;border: 1px solid black">
</div>
<input type="button" value="测试" onclick="testLoad()">
</body>
</html>

 第二个页面

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<div id="a"><li>JAVA</li><li>HTML</li><li>CSS</li><li>Mysql</li><li>python</li>
</div>
</body>
</html>

后台代码

package com.msb.servlet;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.msb.pojo.Student;
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;
/*** @Author: Ma HaiYang* @Description: MircoMessage:Mark_7001*/
@WebServlet("/servlet2.do")
public class Servlet2 extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String username = req.getParameter("username");String password = req.getParameter("password");System.out.println(username);System.out.println(password);resp.setContentType("text/html;charset=UTF-8");resp.setCharacterEncoding("UTF-8");resp.getWriter().print("<h1>hello</h1>");}
}

4.3.1 $.get()

这是一个简单的 GET 请求功能以取代复杂 $.ajax 。请求成功时可调用回调函数。如果需要在出错时执行函数,请使用$.ajax。

语法为: 
$.get(url,[data],[callback],[type])

参数的含义为:

  • url: URL地址 
  • data:待发送参数。 
  • callback:载入成功时回调函数。 

type:返回内容格式,xml, html, script, json, text, _default
该函数是简写的 Ajax 函数,等价于: 

 
$.ajax({type:   'GET',url: url,data: data,success: success,dataType: dataType});

4.3.1 $.getJSON()

JSON是一种较为理想的数据传输格式,它能够很好的融合与JavaScript或其他宿主语言,并且可以被JS直接使用。使用JSON相比传统的通过 GET、POST直接发送“裸体”数据,在结构上更为合理,也更为安全。至于jQuery的getJSON()函数,只是设置了JSON参数的ajax()函数的一个简化版本。语法为:

$.getJSON(url,             //请求URL[data],          //传参,可选参数[callback]       //回调函数,可选参数);

该函数是简写的 Ajax 函数,等价于:

$.ajax({url: url,data: data,success: callback,dataType: json});

仅仅是等效于上述函数,但是除此之外这个函数也是可以跨域使用的,相比get()、post()有一定优势。另外这个函数可以通过把请求url写 成"myurl?callback=X"这种格式,让程序执行回调函数X。
注意:$.getJSON是以GET方式提交数据,如果需要提交很大的数据量,可选$.post

4.$.post()

这是一个简单的 POST 请求功能以取代复杂 $.ajax 。请求成功时可调用回调函数。如果需要在出错时执行函数,请使用$.ajax。

语法为:$.post(url,[data],[callback],[type])
参数的含义为:

 url: URL地址

 data:待发送参数。

 callback:载入成功时回调函数。

 type:返回内容格式,xml, html, script, json, text, _default 
该函数是简写的 Ajax 函数,等价于: 

 
$.ajax({type:   'POST',url: url,data: data,success: success,dataType: dataType});

 前端代码

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script src="js/jquery.min.js"></script><script>function testAjax(){$.get("servlet1.do",{"username":"zhangsan","password":"123456"},function(list){$.each(list,function(i,e){console.log(e)})},"json")console.log("------------------------------")$.getJSON("servlet1.do",{"username":"zhangsan","password":"123456"},function(list){$.each(list,function(i,e){console.log(e)})})console.log("------------------------------")$.post("servlet1.do",{"username":"zhangsan","password":"123456"},function(list){$.each(list,function(i,e){console.log(e)})},"json")}</script>
</head>
<body>
<input type="button" value="测试" onclick="testAjax()">
</body>
</html>

后端代码 

package com.msb.servlet;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.msb.pojo.Student;
import sun.util.calendar.LocalGregorianCalendar;
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;
/*** @Author: Ma HaiYang* @Description: MircoMessage:Mark_7001*/
@WebServlet("/servlet1.do")
public class Servlet1 extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String username = req.getParameter("username");String password = req.getParameter("password");System.out.println(username);System.out.println(password);Student stu1=new Student("小黑","男",10,new Date());Student stu2=new Student("小白","男",10,new Date());Student stu3=new Student("小黄","男",10,new Date());Student stu4=new Student("小花","男",10,new Date());ArrayList<Student> list =new ArrayList<>();Collections.addAll(list,stu1,stu2,stu3,stu4);GsonBuilder gb =new GsonBuilder();gb.setDateFormat("yyyy-MM-dd");Gson gson = gb.create();String json = gson.toJson(list);resp.setContentType("text/html;charset=UTF-8");resp.setCharacterEncoding("UTF-8");resp.getWriter().print(json);}
}

 

jsonp跨域处理

4.4.1 什么是跨域?

出于浏览器的同源策略限制。同源策略(Sameoriginpolicy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。同源策略会阻止一个域的javascript脚本和另外一个域的内容进行交互。所谓同源(即指在同一个域)就是两个页面具有相同的协议(protocol),主机(host)和端口号(port)
本地路径地址:http://127.0.0.1:8080/msb/index.jsp
https://127.0.0.1:8080/msb/index.jsp 协议不一样
http://192.168.24.11:8080/msb/index.jsp IP不一致
http://127.0.0.1:8888/msb/index.jsp 端口不一致
http://localhost:8080/msb/index.jsp IP不一致

演示代码如下 

使用Hbuider编写如下代码

<html>
<head><title>$Title%sSourceCode%lt;/title><meta charset="UTF-8"/><script src="js/jquery.min.js"></script><script>function checkUname(){// 获取输入框中的内容if(null == $("#unameI").val() || '' == $("#unameI").val()){$("#unameInfo").text("用户名不能为空");return;}$("#unameInfo").text("");// 通过jQuery.ajax() 发送异步请求$.ajax({type:"GET",// 请求的方式 GET  POSTurl:"http://localhost:8080/ajaxDemo3_war_exploded/unameCheckServlet.do?", // 请求的后台服务的路径data:"uname="+$("#unameI").val(),// 提交的参数success:function(info){ // 响应成功执行的函数$("#unameInfo").text(info)}})}</script>
</head>
<body>
<form action="myServlet1.do" >用户名:<input id="unameI" type="text" name="uname" onblur="checkUname()"><span id="unameInfo" style="color: red"></span><br/>密码:<input type="password" name="pwd"><br/><input type="submit" value="提交按钮">
</form>
</body>
</html>

 

浏览器请求该资源的地址是:
http://127.0.0.1:8020/testa/index.html 
但是其内部ajax请求的资源的是:

http://localhost:8080/ajaxDemo3_war_exploded/unameCheckServlet.do? 
二者端口号和IP其实是不一致的,这就受到同源策略的控制

实现的原理是什么?

我们发现Web页面上调用js文件时则不受是否跨域的影响,拥有”src”这个属性的标签都却拥有跨域的能力,比如<\script>、<\img>、<\iframe>。那么跨域访问数据就有了一种可能,那就是在远程服务器上设法把数据装进js格式的文件里,供客户端调用和进一步处理。就好比使用一个<script>,让其src属性指向我们要访问的跨域资源,然后以接收js文件的形式接收数据

  • 通过:dataType:'jsonp'属性实现跨域请求
  •   通过 jsonp:'callback',属性简化回调函数处理

通过 jsonp:’callback’,实现自动处理回调函数名,相当于在url地址栏最后后拼接一个callback=函数名,后台自动根据这个函数名处理JS脚本,jQuery也会根据这函数名自动在前端处理回调函数,这样我们直接在success方法中接收返回的数据即可,可以不用自己去自己定义回调函数.后台获取参数时,参数名要要和jsonp:后面的函数名保持一致

页面代码

<html>
<head><title>$Title%sSourceCode%lt;/title><meta charset="UTF-8"/><script src="http://localhost:8080/ajaxDemo3_war_exploded/js/jquery.min.js"></script><script>function checkUname(){// 获取输入框中的内容if(null == $("#unameI").val() || '' == $("#unameI").val()){$("#unameInfo").text("用户名不能为空");return;}$("#unameInfo").text("");// 通过jQuery.ajax() 发送异步请求$.ajax({type:"GET",// 请求的方式 GET  POSTurl:"http://localhost:8080/ajaxDemo3_war_exploded/unameCheckServlet.do?", // 请求的后台服务的路径data:{uname:$("#unameI").val()},// 提交的参数dataType:"jsonp",jsonp:"aaa",success:function(info){$("#unameInfo").text(info)}})}</script>
</head>
<body>
<form action="myServlet1.do" >用户名:<input id="unameI" type="text" name="uname" onblur="checkUname()"><span id="unameInfo" style="color: red"></span><br/>密码:<input type="password" name="pwd"><br/><input type="submit" value="提交按钮">
</form>
</body>
</html>

 后端代码

package com.msb.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;
/*** @Author: Ma HaiYang* @Description: MircoMessage:Mark_7001*/
@WebServlet("/unameCheckServlet.do")
public class UnameCheckServlet extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String uname = req.getParameter("uname");String callBack = req.getParameter("aaa");System.out.println(uname);String info="";if("msb".equals(uname)){info="用户名已经占用";}else{info="用户名可用";}// 向浏览器响应数据resp.setCharacterEncoding("UTF-8");resp.setContentType("text/javaScript;charset=UTF-8");resp.getWriter().print(callBack+"('"+info+"')");}
}

通过getJson方实现跨域请求

getJSON方法是可以实现跨域请求的,在用该方法实现跨域请求时,在传递参数上应该注意在url后拼接一个jsoncallback=?,jQuery会自动替换?为正确的回调函数名,我们就可以不用单独定义回调函数了

 前端代码
 

<html>
<head><title>$Title%sSourceCode%lt;/title><meta charset="UTF-8"/><script src="http://localhost:8080/ajaxDemo3_war_exploded/js/jquery.min.js"></script><script>function checkUname(){// 获取输入框中的内容if(null == $("#unameI").val() || '' == $("#unameI").val()){$("#unameInfo").text("用户名不能为空");return;}$("#unameInfo").text("");$.getJSON("http://localhost:8080/ajaxDemo3_war_exploded/unameCheckServlet.do?jsoncallback=?",{uname:$("#unameI").val()},function(info){$("#unameInfo").text(info)})}</script>
</head>
<body>
<form action="myServlet1.do" >用户名:<input id="unameI" type="text" name="uname" onblur="checkUname()"><span id="unameInfo" style="color: red"></span><br/>密码:<input type="password" name="pwd"><br/><input type="submit" value="提交按钮">
</form>
</body>
</html>

 后台代码

package com.msb.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;
/*** @Author: Ma HaiYang* @Description: MircoMessage:Mark_7001*/
@WebServlet("/unameCheckServlet.do")
public class UnameCheckServlet extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String uname = req.getParameter("uname");String callBack = req.getParameter("jsoncallback");System.out.println(uname);String info="";if("msb".equals(uname)){info="用户名已经占用";}else{info="用户名可用";}// 向浏览器响应数据resp.setCharacterEncoding("UTF-8");resp.setContentType("text/javaScript;charset=UTF-8");resp.getWriter().print(callBack+"('"+info+"')");}
}

拓展:通过后台代码也可以实现跨域,一般在过滤器中添加如下代码,那么前端在请求时就不用考虑跨域问题了

/*请求地址白名单 *代表所有    */
  resp.setHeader("Access-Control-Allow-Origin", "*");
  /*请求方式白名单      */
  resp.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
  resp.setHeader("Access-Control-Max-Age", "3600");
  resp.setHeader("Access-Control-Allow-Headers", "x-requested-with");
 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_226310.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

黑苹果之微星(MSI)主板BIOS详细设置篇

很多童鞋安装黑苹果的时候会卡住&#xff0c;大部分原因是cfg lock 没有关闭&#xff0c;以及USB端口或SATA模式设置错误。 为了避免这些安装阶段报错的情况发生&#xff0c;今天给大家分享一下超详细的BIOS防踩坑设置指南--微星&#xff08;MSI&#xff09;主板BIOS篇&#xf…

CTFHub | Refer注入

0x00 前言 CTFHub 专注网络安全、信息安全、白帽子技术的在线学习&#xff0c;实训平台。提供优质的赛事及学习服务&#xff0c;拥有完善的题目环境及配套 writeup &#xff0c;降低 CTF 学习入门门槛&#xff0c;快速帮助选手成长&#xff0c;跟随主流比赛潮流。 0x01 题目描述…

天然气潮流计算matlab程序

天然气潮流计算matlab程序 1 天然气潮流计算理论 由于天然气涉及到流体的运动方程&#xff0c;直接计算非常复杂&#xff0c;因此需要提前做出一些假设来简化计算&#xff0c;经过研究&#xff0c;适当的假设对结果影响很小&#xff0c;因此本文对天然气系统做出如下假设&#…

MNN--初步学习

来自阿里MNN有三个贡献点&#xff1a; 提出了预推理机制&#xff0c;在线计算推理成本和最优方案优化了kernel提出后端抽象实现混合调度MNN的架构&#xff1a; 分离线和在线两部分。离线就是很传统的模型转换、优化、压缩、量化的那一套东西&#xff0c;这里mnn转出的模型文件…

springboot thymeleaf使用

导入依赖 <dependency> <groupId>org.thymeleaf</groupId> <artifactId>thymeleaf</artifactId> <version>3.0.11.RELEASE</version> </dependency> <dependency> <groupId>org.thymeleaf</groupId> <a…

人口数据集:地级市常住人口与户籍人口、人口1%抽样调查数据两大维度指标数据

一、地级市常住人口与户籍人口 1、数据来源&#xff1a;地级市常住人口数据&#xff08;主要来源于各地政府公报&#xff09;&#xff0c;户籍人口数据来源于《中国城市统计年鉴》 2、时间跨度&#xff1a;2003-2019年 3、区域范围&#xff1a;280个地级市 4、指标说明&…

牛顿法(牛顿拉夫逊)配电网潮流计算matlab程序

牛顿法配电网潮流计算matlab程序 传统牛顿—拉夫逊算法&#xff0c;简称牛顿法&#xff0c;是将潮流计算方程组F(X)0&#xff0c;进行泰勒展开。因泰勒展开有许多高阶项&#xff0c;而高阶项级数部分对计算结果影响很小&#xff0c;当忽略一阶以上部分时&#xff0c;可以简化对…

校园论坛设计(Java)——介绍篇

校园论坛设计&#xff08;Java&#xff09; 文章目录校园论坛设计&#xff08;Java&#xff09;0、写在前面1、项目介绍2、项目背景3、项目功能介绍3.1 总体设计图3.2 帖子模块3.3 学习模块3.4 个人信息模块3.5 数据报表模块3.6 校园周边模块3.7 用户管理模块3.8 登录注册模块4…

[足式机器人]Part3机构运动微分几何学分析与综合Ch02-3 平面机构离散运动鞍点综合——【读书笔记】

本文仅供学习使用 本文参考&#xff1a; 《机构运动微分几何学分析与综合》-王德伦、汪伟 《微分几何》吴大任 Ch02-3 平面机构离散运动鞍点综合2.4 鞍滑点2.4.1 鞍线与二副连架杆P-R2.4.2 鞍线误差2.4.3 三位置鞍线2.4.4 四位置鞍线2.4.5 多位置鞍线2.4.6 滑点与鞍滑点2.4 鞍滑…

问题盘点|使用 Prometheus 监控 Kafka,我们该关注哪些指标

Kafka 作为当前广泛使用的中间件产品&#xff0c;承担了重要/核心业务数据流转&#xff0c;其稳定运行关乎整个业务系统可用性。本文旨在分享阿里云 Prometheus 在阿里云 Kafka 和自建 Kafka 的监控实践。01Kafka 简介Aliware01Kafka 是什么&#xff1f;Kafka 是分布式、高吞吐…

力扣(LeetCode)88. 合并两个有序数组(C++)

朴素思想 朴素思想&#xff0c;开第三个数组&#xff0c;对 nums1nums1nums1 和 nums2nums2nums2 进行二路归并。 class Solution { public:void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {vector<int> nums3(mn);int i 0,j …

创新赋能合作伙伴,亚马逊云科技re:Invent科技盛宴

北京时间11月29号&#xff0c;亚马逊云科技年度峰会re:Invent 2022将在拉斯维加斯开幕。这场年度最重磅的云计算技术大会不仅是科技盛宴&#xff0c;也是亚马逊云科技与诸多客户交流互鉴的绝佳平台&#xff0c;今天带大家认识一下几位资深云计算用户&#xff0c;以及他们和re:I…

Pytorch 中Label Smoothing CrossEntropyLoss实现

一. 前言 一般情况下我们都是直接调用Pytorch自带的交叉熵损失函数计算loss&#xff0c;但涉及到魔改以及优化时&#xff0c;我们需要自己动手实现loss function&#xff0c;在这个过程中如果能对交叉熵损失的代码实现有一定的了解会帮助我们写出更优美的代码。 其次是标签平…

【架构设计】作为架构师你应该掌握的画图技术

1.前言 大家知道&#xff0c;架构的过程其实就是建模的过程&#xff0c;那自然离不开架构图。那么&#xff0c;我们先来看几个问题。 &#xff08;1&#xff09;什么是架构图&#xff1f; 架构图 架构 图&#xff0c;用图的形式把系统架构展示出来&#xff0c;配上简单的文…

基于C#的校园闲置物品共享系统的开发和实现(Asp.net+Web)

目 录 摘 要 I Abstract II 第1章 绪论 1 1.1选题背景 1 1.1.1校园闲置物品共享系统的开发背景 1 1.1.2学生闲置物品交易活动的现状 1 1.2 校园闲置物品共享系统的研究方向和内容 1 1.2.1研究方向 1 1.2.2研究内容 2 1.3 校园闲置物品共享系统的设计目标 2 1.4 校园闲置物品共…

多云加速云原生数仓生态,华为与 HashData 联合打造方案

多云的兴起&#xff0c;源于用户应用对于基础设施、云服务功能、安全性等的差异化需求&#xff0c;用户希望根据需求将应用、数据因“云”制宜&#xff0c;实现业务的高度灵活性和高效性。这也直接驱动着云原生数据仓库等一批云原生应用的流行&#xff0c;以及存储等基础设施加…

WR | 水源水耐药基因稳定赋存的关键:以致病菌为“源”,群落构建主导菌为“汇”...

第一作者&#xff1a;武冬通讯作者&#xff1a;David W.Graham、杨凯、谢冰通讯单位&#xff1a;华东师范大学生态与环境科学学院&#xff0c;英国纽卡斯尔大学工程学院文章链接&#xff1a;www.sciencedirect.com/science/article/pii/S0043135422013045- 成果简介 -近日&…

【食品加工技术】第五章 烘烤食品加工技术 笔记

【食品加工技术】第五章 烘烤食品加工技术 笔记5.1 焙烤食品概述烘烤食品的分类按发酵和膨化程度分类安装生产工艺分类烘烤食品的原料面粉糖蛋品乳及乳制品膨松剂烘烤设备常用设备恒温设备常用工具5.2 面包加工工艺和关键技术面包的分类面包的发酵原理面包的工艺流程一次发酵二…

HTML CSS个人网页设计与实现——人物介绍丁真(学生个人网站作业设计)

&#x1f389;精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业…

iwebsec靶场 SQL注入漏洞通关笔记6- 宽字节注入

系列文章目录 iwebsec靶场 SQL注入漏洞通关笔记1- 数字型注入_mooyuan的博客-CSDN博客 iwebsec靶场 SQL注入漏洞通关笔记2- 字符型注入&#xff08;宽字节注入&#xff09;_mooyuan的博客-CSDN博客 iwebsec靶场 SQL注入漏洞通关笔记3- bool注入&#xff08;布尔型盲注&#…