300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > AJAX异步请求解决跨域问题的三种方式

AJAX异步请求解决跨域问题的三种方式

时间:2021-04-28 21:36:46

相关推荐

AJAX异步请求解决跨域问题的三种方式

一 什么是跨域

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

例如:

本地路径地址:http://127.0.0.1:8080/msb/index.jsphttps://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不一致

二 解决AJAX跨域请求的三种方式

方式一jsonp跨域处理

代码演示如下:

前端页面

<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’,实现自动处理回调函数名,相当于在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>

后端代码

@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>

后台代码

@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");

方第三 在controller上使用@CrossOrigin注解

属性:

origins : 允许可访问的域列表IPmaxAge:准备响应前的缓存持续的最大时间(以秒为单位)。

代码实现:

@CrossOrigin(origins = "", maxAge = 3600)@RestController@RequestMapping("/account")public class AccountController {@GetMapping("/{id}")public Account receive(@PathVariable Long id) { }}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。