Ajax:ajax实现跨域解决方案jsonp
才发送请求,然后执行servlet,servlet给它响应一段js代码回去,它接收到js代码解释并执行,显示效果,它并没有达到局部刷新的效果,我们让它达到局部刷新的效果,我们点击某一个按钮,我们让它局部刷新,显然上面让页面打开的时候加载script标签就不行了,我们可以让他先加载完,点击页面某一个按钮去加载script标签,来达到页面的局部刷新,整个过程跟ajax没有关系。当out.print("
目录:
(1)ajax跨域解决方案值jsonp方式初步
(2)ajax跨域解决方案值jsonp方式深入
(3)ajax跨域解决方案之jQuery封装jsonp
(1)ajax跨域解决方案值jsonp方式初步
ajax2.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>jsonp实现跨域</title>
</head>
<body>
<script type="text/javascript">
/**
* 这是我自定义的函数
*/
function sayHello(data){
//alert("hello world!")
alert("hello," + data.name)
}
function sum(){
alert("求和。。。")
}
</script>
<!--超链接也可以跨域呀?为什么不用呢?因为超链接点击之后会跳转页面,无法做到页面局部刷新效果。-->
<!--script标签是可以跨域的。src属性可以是xxx.js文件,那这个路径可以是一个servlet路径吗?可以-->
<script type="text/javascript" src="http://localhost:8081/b/jsonp1?fun=sum"></script>
</body>
</html>
JSONPServlet1:
package com.bjpowernode.b.web.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;
import java.io.PrintWriter;
@WebServlet("/jsonp1")
public class JSONPServlet1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 在后台输出
//System.out.println("jsonp方式完成跨域访问");
// 向前端响应一段js代码呢?
PrintWriter out = response.getWriter();
//out.print("alert(123)"); // 这是响应一段js代码,只不过这个alert函数是JS内置的函数,可以直接用。
// 注意:不要误以为是后端java代码调用了sayHello()函数,实际上后端只负责响应一个字符串回去。
// 真正的调用者,还是浏览器,浏览器接收到这个字符串之后,会自动将这个字符串当做一段js代码解释执行。
//out.print("sayHello()"); // 这也是响应一段JS代码。只不过这个sayHello函数是程序员自定义的。
//响应一段js代码,然后传一个json数据给前端
//out.print("sayHello({\"name\" : \"jackson\"})");
// 动态获取函数名
String fun = request.getParameter("fun");
//out.print(fun + "({\"name\" : \"jackson\"})");
out.print(fun + "()");
}
}
out.print会向前端<script>中返回js代码,前端页面并解析js代码执行
当:System.out.println("jsonp方式完成跨域访问");
当:out.print("alert(123)")
当:out.print("sayHello()")
当:out.print("sayHello({\"name\" : \"jackson\"})")
当 :out.print(fun + "()");
(2)ajax跨域解决方案值jsonp方式深入
以上代码在ajax2.html页面它在打开的时候,从上往下开始执行,执行到:
<script type="text/javascript" src="http://localhost:8081/b/jsonp1?fun=sum"></script>
才发送请求, 然后执行servlet,servlet给它响应一段js代码回去,它接收到js代码解释并执行,显示效果,它并没有达到局部刷新的效果,我们让它达到局部刷新的效果,我们点击某一个按钮,我们让它局部刷新,显然上面让页面打开的时候加载script标签就不行了,我们可以让他先加载完,点击 页面某一个按钮去加载script标签,来达到页面的局部刷新,整个过程跟ajax没有关系
设计一个按钮点击之后触发script,发起请求,从后端获取数据之后,再把获取到的数据在下方div中显示
ajax3.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>jsonp跨域</title>
</head>
<body>
<!--<script type="text/javascript" src="http://localhost:8081/b/jsonp2?fun=sayHello"></script>-->
<script type="text/javascript">
// 自定义的函数
function sayHello(data){ // data是一个json:{"username" : "lucy"}
document.getElementById("mydiv").innerHTML = data.username
}
window.onload = () => {
document.getElementById("btn").onclick = () => {
// 加载script元素
// 创建script元素对象
const htmlScriptElement = document.createElement("script");
// 设置script的type属性
htmlScriptElement.type = "text/javascript"
// 设置script的src属性
htmlScriptElement.src = "http://localhost:8081/b/jsonp2?fun=sayHello"
// 将script对象添加到body标签中(这一步就是加载script)
document.getElementsByTagName("body")[0].appendChild(htmlScriptElement)
}
}
</script>
<button id="btn">jsonp解决跨域问题,达到ajax局部刷新的效果</button>
<div id="mydiv"></div>
</body>
</html>
JSONPServlet2:
package com.bjpowernode.b.web.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("/jsonp2")
public class JSONPServlet2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 获取函数名
String fun = request.getParameter("fun");
// 响应一段js代码 lucy可能是从数据库查询的名字
response.getWriter().print(fun + "({\"username\" : \"lucy\"})");
}
}
点击按钮:
(3)ajax跨域解决方案之jQuery封装jsonp
把别人封装好的jQuery库复制到项目中:
ajax4.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>jQuery的jsonp封装解决ajax跨域问题</title>
</head>
<body>
<!--引入jQuery库:这个jQuery库是官网的,不是咱们手写封装的山寨版。-->
<script type="text/javascript" src="/a/js/jquery-3.6.0.min.js"></script>
<script type="text/javascript">
// 这个函数不需要你写,jQuery可以自动帮助你生成
//function jQuery3600508253314856699_1655528968612(json){ // 系统自动生成的这个函数默认情况,会自动调用success的回调函数。 }
$(function(){
$("#btn").click(function(){
// 发送所谓的ajax请求(其实本质上并不是一个ajax请求。只是披着ajax的皮。乔装打扮的ajax。)
$.ajax({
type : "GET", // jsonp请求只支持get请求。
// 虽然这里的url是这样写的,但实际上发送的请求是:/b/jsonp3?callback=jQuery3600508253314856699_1655528968612&_=1655528968613
// callback=jQuery3600508253314856699_1655528968612
// callback就是我们之前的fun
// jQuery3600508253314856699_1655528968612就是我们之前的sayHello,而这个名字是jQuery自动为我们生成的。
url : "http://localhost:8081/b/jsonp3",
dataType : "jsonp", // 指定数据类型是jsonp形式。【最关键的是它】
success : function(data){ // data变量用来接收服务器端的响应(data是一个json:{"username":"lisi"})
$("#mydiv").html("欢迎你:" + data.username)
}
})
})
})
</script>
<button id="btn">jQuery库封装的jsonp</button>
<div id="mydiv"></div>
</body>
</html>
JSONPServlet3:
package com.bjpowernode.b.web.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("/jsonp3")
public class JSONPServlet3 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 获取函数名 默认的是callback
String callback = request.getParameter("callback");
// 响应一段js代码,调用函数
response.getWriter().print(callback + "({\"username\":\"lisi\"})");
}
}
可以自己设置回调函数:
ajax4.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>jQuery的jsonp封装解决ajax跨域问题</title>
</head>
<body>
<!--引入jQuery库:这个jQuery库是官网的,不是咱们手写封装的山寨版。-->
<script type="text/javascript" src="/a/js/jquery-3.6.0.min.js"></script>
<script type="text/javascript">
// 这个函数不需要你写,jQuery可以自动帮助你生成
//function jQuery3600508253314856699_1655528968612(json){ // 系统自动生成的这个函数默认情况,会自动调用success的回调函数。 }
// 自定义的函数
function sayHello(data){
$("#mydiv").html("欢迎你:" + data.username)
}
$(function(){
$("#btn").click(function(){
// 发送所谓的ajax请求(其实本质上并不是一个ajax请求。只是披着ajax的皮。乔装打扮的ajax。)
$.ajax({
type : "GET", // jsonp请求只支持get请求。
// 虽然这里的url是这样写的,但实际上发送的请求是:/b/jsonp3?callback=jQuery3600508253314856699_1655528968612&_=1655528968613
// callback=jQuery3600508253314856699_1655528968612
// callback就是我们之前的fun
// jQuery3600508253314856699_1655528968612就是我们之前的sayHello,而这个名字是jQuery自动为我们生成的。
url : "http://localhost:8081/b/jsonp3",
dataType : "jsonp", // 指定数据类型是jsonp形式。【最关键的是它】
jsonp : "fun", // 不采用默认的参数名callback,用这个属性来指定具体的参数名。
jsonpCallback : "sayHello" // 不采用默认的回调函数,用这个属性来指定具体的回调函数。
/*success : function(data){ // data变量用来接收服务器端的响应(data是一个json:{"username":"lisi"})
$("#mydiv").html("欢迎你:" + data.username)
}*/
})
})
})
</script>
<button id="btn">jQuery库封装的jsonp</button>
<div id="mydiv"></div>
</body>
</html>
JSONPServlet3:
package com.bjpowernode.b.web.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("/jsonp3")
public class JSONPServlet3 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 获取函数名 默认callback
//String callback = request.getParameter("callback");
String callback = request.getParameter("fun");
// 响应一段js代码,调用函数
response.getWriter().print(callback + "({\"username\":\"lisi\"})");
}
}
启动项目:如果这个jQuery报404,可能是没有导入到项目中,可以去项目的底层目录下去查看
发现真的没有赋值的那个jQuery-3.6.0.min.js
这时需要 Rebuild一下a Model
在查看底层目录下,就出现了js目录
重新刷新页面:响应成功
更多推荐
所有评论(0)