tomcat|ajax跨域的几种解决方案


ajax跨域

    • AJAX跨域请求
    • GetJson实现跨域请求
    • CrossOrigin注解实现跨域

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

AJAX跨域请求 下面简单模拟一个场景----->>
前端有一个页面
tomcat|ajax跨域的几种解决方案
文章图片

鼠标离开用户名输入框时,检查是否符合要求,如果为空,则给提示,如果不为空,则异步查询数据库,后返回结果;
本次请求的页面是8082端口的,而响应的ajax路径却是8080端口的
前端代码—>
$Title%sSourceCod - 锐客网 src="https://www.it610.com/article/js/jquery-3.5.1.min.js"> > function checkUname(){ // 获取输入框中的内容 if(null == $("#unameI").val() || '' == $("#unameI").val()){ $("#unameInfo").text("用户名不能为空"); return; } $("#unameInfo").text(""); // 通过jQuery.ajax() 发送异步请求 $.ajax( { type:"GET",// 请求的方式 GETPOST url:"http://localhost:8080/loadPicture_war_exploded/checkName.do?", // 请求的后台服务的路径 data:"uname="+$("#unameI").val(),// 提交的参数 success:function(info){ // 响应成功执行的函数 $("#unameInfo").text(info) } } ) }
用户名: id="unameInfo" style="color: red">
密码:

后端代码—>
package com.gavin.controller; 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 testAjax extends HttpServlet { @Override protected 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 ("gavin".equals(uname)) { info = "用户名已经占用"; } else { info = "用户名可用"; } // 向浏览器响应数据 resp.setCharacterEncoding("UTF-8"); resp.setContentType("text/javaScript; charset=UTF-8"); resp.getWriter().print(callBack + "('" + info + "')"); } }

访问的时候浏览器提示—>
tomcat|ajax跨域的几种解决方案
文章图片

原因—>
对 CORS 请求的响应缺少必需的Access-Control-Allow-Origin头,其用于确定在当前源内操作的资源是否可以访问。如果服务器在您的控制之下,请将请求站点的源添加到允许访问的域集,方法是将其添加到Access-Control-Allow-Origin头的值。

tomcat|ajax跨域的几种解决方案
文章图片

为什么会有跨域呢?
因为实际应用中分布式与集群会涉及到跨域,前端服务器与后端服务器分离,前端服务异步请求后端服务器就涉及到了跨域;
由于浏览器的同源策略,所以跨服务器访问会有一些小麻烦,先一步一步探索去解决;
tomcat|ajax跨域的几种解决方案
文章图片

这个时候js文件能不能加载生效呢? 答案是生效了;
tomcat|ajax跨域的几种解决方案
文章图片

Web页面上调用js文件时可以跨域,也就是后拥有”src”这个属性的标签都却拥有跨域的能力
那么我们转变思路,如果将异步请求转到js文件身上
比如我们可以这么做
tomcat|ajax跨域的几种解决方案
文章图片

后端可以接收到前端数据;
但是这样写看起来怪怪的,而且实际上这样异步请求中的url依然会被浏览器拦截
tomcat|ajax跨域的几种解决方案
文章图片

如果去掉这个url,会发生不可描述的事情,像这样----整个span被页面代码填满,
tomcat|ajax跨域的几种解决方案
文章图片

那怎么处理呢?
此时异步请求添加一个属性—dataType:“jsonp”
这样就可以正常一点实现跨域的异步请求了—>
function checkUname(){ // 获取输入框中的内容 if(null == $("#unameI").val() || '' == $("#unameI").val()){ $("#unameInfo").text("用户名不能为空"); return; } $("#unameInfo").text(""); // 通过jQuery.ajax() 发送异步请求 $.ajax( { type:"GET",// 请求的方式 GETPOST url:"http://localhost:8080/loadPicture_war_exploded/checkName.do?", // 请求的后台服务的路径 data:"uname="+$("#unameI").val(),// 提交的参数 dataType:"jsonp", success:function(info){ // 响应成功执行的函数 $("#unameInfo").text(info) } } ) }

tomcat|ajax跨域的几种解决方案
文章图片

tomcat|ajax跨域的几种解决方案
文章图片

原因---->>
tomcat|ajax跨域的几种解决方案
文章图片

虽然跨域请求实现了,但是前端接收不到后端返回的数据,即异步 请求中的success方法失效了,
为什么失效?因为如果是通过script来完成异步请求,那么返回的内容应该是一个js代码,
tomcat|ajax跨域的几种解决方案
文章图片

tomcat|ajax跨域的几种解决方案
文章图片

既然是这样,我们要想在span中添加返回类的信息,那么我们不妨在前端写一个方法,用于专门像span中添加信息—然后后端返回的信息来直接调这个方法就好了;
function showInfo(info){ $("#unameInfo").val(info); }

后端返回的数据
tomcat|ajax跨域的几种解决方案
文章图片

tomcat|ajax跨域的几种解决方案
文章图片

运行原理------>>>>
tomcat|ajax跨域的几种解决方案
文章图片

解决一个小痛点,前端方法名随时可能变化,为了降低耦合度,一般会这么做,前端发送的数据中携带该方法名;
tomcat|ajax跨域的几种解决方案
文章图片

tomcat|ajax跨域的几种解决方案
文章图片

前面不是说success废了吗?我就想用这个方法,不想在额外定义一个别的showInfo方法,那么这个该怎么做呢?
在异步请求上添加一个参数:
jsonp:“任意的名称A”
tomcat|ajax跨域的几种解决方案
文章图片

tomcat|ajax跨域的几种解决方案
文章图片

GetJson实现跨域请求
function checkUname(){ // 获取输入框中的内容 if(null == $("#unameI").val() || '' == $("#unameI").val()){ $("#unameInfo").text("用户名不能为空"); return; } $("#unameInfo").text(""); $.getJSON( "http://localhost:8080/loadPicture_war_exploded/checkName.do?jsoncallback=?", {uname:$("#unameI").val()}, function(info){ $("#unameInfo").text(info) }) }

tomcat|ajax跨域的几种解决方案
文章图片

通过后台代码也可以实现跨域,一般在过滤器中添加如下代码,那么前端在请求时就不用考虑跨域问题了
/*请求地址白名单 *代表所有 /
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”);
在结合springmvc之后,可以通过一个注解来完成跨域
CrossOrigin注解实现跨域 tomcat|ajax跨域的几种解决方案
文章图片
tomcat|ajax跨域的几种解决方案
文章图片

package com.gavin.controller; import com.gavin.pojo.AlertMsg; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; @Controller public class AjaxTEST{@CrossOrigin(value ="http://127.0.0.1:8020" ) @RequestMapping("/checkName3.do") @ResponseBody public AlertMsg checkUserName(@RequestBody AlertMsg alertMsg){ System.out.println(alertMsg); if ("gavin".equals(alertMsg.getUname())) { alertMsg.setMsg("用户名已经占用"); } else { alertMsg.setMsg( "用户名可用"); } // 向浏览器响应数据----返回一个json格式的数据 System.out.println(alertMsg); return alertMsg; } }

function checkUname3() { // 获取输入框中的内容 if(null == $("#unameI3").val() || '' == $("#unameI3").val()) { $("#unameInfo3").text("用户名不能为空"); return; } $("#unameInfo3").text(""); var str = $("#unameI3").val(); $.ajax({ type: "post", url: "http://localhost:8080/loadPicture_war_exploded/checkName3.do?", //data:{uname:$("#unameI3").val(),msg:""}, //data:{"uname":$("#unameI3").val(),"msg":""}, data: JSON.stringify({ uname: $("#unameI3").val()}), dataType: "json", contentType: "application/json; charset=UTF-8", success: function(data) {$("#unameInfo3").text(data.msg); } }); }

tomcat|ajax跨域的几种解决方案
文章图片

tomcat|ajax跨域的几种解决方案
文章图片

【tomcat|ajax跨域的几种解决方案】关于json对象的一些感悟与理解;
前端传过来的数据----可能是字符串,也可能是json对象,但是在处理的时候还是以字符串进行处理的,
JSON.stringify()方法是将一个JavaScript对象转换成符合JSON格式的字符串,然后后端通过解析字符串在转化为一个json对象;
所以tomcat|ajax跨域的几种解决方案
文章图片

ajax跨域的解决方案有种了,
第一种是 jsonp的形式,
另一种是getjson()
最后一种是注解CrossOrigin

    推荐阅读