10、JSONP实现Ajax的跨域请求

本文详细介绍了跨域的概念及其实现方法,包括通过代理、动态创建script标签、使用jQuery的ajax和jsonp、升级版的XMLHttpRequest等方式实现跨域请求,并提供了具体的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、什么是跨域

     协议名称和端口号不一样。

2、跨域请求的实现一般方法

1.1 通过代理的方式

      在Java代码里面,去访问跨域的请求


1.2 通过动态创建script标签

1. JavaScript代码

     <head>
		<meta charset="utf-8" />
		<title>Ajax的跨域访问</title>
		<script type="text/javascript">
			//1、用于动态创建script标签的函数
			function cerateScript(src) {
				var dynScript = document.createElement('script');
				dynScript.src = src;
				dynScript.setAttribute("type", "text/javascript");
				document.getElementsByTagName('head')[0]
					.appendChild(dynScript);

			}
			//2、回调函数,对返回数据的处理
			//通过动态标签注入的必须是可执行的JavaScript代码,因此无论是你的数据格式是啥(xml、json等),都必须封装在一个回调函数中。一个回调函数如下:
			function dynCallback(data) {
				//对返回的数据进行处理
				alert(data.age);
			}
			//3、服务端返回数据的格式,需要将数据封装在上面这个dynCallback函数中,如下:
			//dynCallback({age:18})

			//4、动态的创建script标签,实现跨域调用
			cerateScript("http://localhost:8080/Jsonp/JsonpServlet?callback=dynCallback");
		</script>
	</head>


2. 后台Servlet代码

public class JsonpServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		// 获取回调函数的名称
		String callback = request.getParameter("callback");

		// 拼接jsonp,用于前端函数的回调
		// callback ({"age":"18");
		String jsonpResult = callback + "(" + "{ " + "\"age\":\"18\"" + "}"
				+ " )";
		PrintWriter writer = response.getWriter();
		writer.write(jsonpResult);
		writer.flush();
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		doGet(request, response);
	}

}


1.3 jquery通过ajax和jsonp来实现跨域

1.前端JavaScript代码

<!DOCTYPE html>
<html>

	<head>
		<meta charset="utf-8" />
		<title>Ajax的跨域访问</title>
		<script type="text/javascript" src="js/jquery.min.js"></script>
		<script type="text/javascript">
			/*jquery不支持post请求的跨域*/
			$(function() {
				$('#btn').click(function() {
					$.ajax({
						type: "get",
						url: "http://localhost:8080/Jsonp/JsonpServlet",
						dataType: "jsonp",
						jsonp: "callback", //默认为callback
						success: function(data, textStatus) {
							alert(data.age);
						},
						error: function() {
							alert('fail');
						}
					});
				});
			});
		</script>
	</head>

	<body>
		<button id="btn" type="button">点击</button>
	</body>

</html>

2.Java的Servlet的代码

public class JsonpServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		// 获取回调函数的名称
		String callback = request.getParameter("callback");

		// 拼接jsonp,用于前端函数的回调
		// callback ({"age":"18");
		String jsonpResult = callback + "(" + "{ " + "\"age\":\"18\"" + "}"
				+ " )";
		PrintWriter writer = response.getWriter();
		writer.write(jsonpResult);
		writer.flush();
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		doGet(request, response);
	}

}


1.4 通过升级版的XmlHttpRequest来实现跨域(正常形似的访问)

1、XMLHttpRequest升级版已经实现了跨域请求。不过需要在后台设置:header("Access-Control-Allow-Origin:http://www.a.com");表示某个域下允许跨域访问。

2、IE:需要使用XDomainRequest()。同样需要在后台设置:response.addHeader("Access-Control-Allow-Origin","*");

3、如果后台语言为java的话,需要自己写一个CrossDomainFilter,在过滤器中设置跨域访问,否则上传不成功。

4、前台代码

<!DOCTYPE html>
<html>

	<head>
		<meta charset="utf-8" />
		<title>Ajax的跨域访问</title>
		<script type="text/javascript" src="js/jquery.min.js"></script>
		<script type="text/javascript">
			/*jquery不支持post请求的跨域*/
			$(function() {
				$('#btn').click(function() {
					$.ajax({
						type: "get",
						url: "http://127.0.0.1:8080/Jsonp/EnServlet",
						success: function(data, textStatus) {
							//数据的处理,转换为json对象
							var jsonObj = JSON.parse(data);
							alert('success');
							alert(jsonObj.age);
						},
						error: function() {
							alert('fail');
						}
					});
				});
			});
		</script>
	</head>

	<body>
		<button id="btn" type="button">点击</button>
	</body>

</html>


5、后台代码

public class EnServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		String jsonpResult = "{ " + "\"age\":\"18\"" + "}";
		PrintWriter writer = response.getWriter();
		writer.write(jsonpResult);
		writer.flush();

	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		doGet(request, response);
	}

}


6、过滤器

public class CrossDomainFilter implements Filter {

	public void destroy() {
	}

	public void doFilter(ServletRequest req, ServletResponse resp,
			FilterChain chain) throws IOException, ServletException {
		HttpServletResponse res = (HttpServletResponse) resp;
		// 这里最好不要写通配符,如果允许多个域请求数据的话,可以直接用逗号隔开:"http://www.baidu.com,http://google.com"
		// 设置允许夸晕访问的主机
		res.setHeader("Access-Control-Allow-Origin", "*");
		// 设置允许跨域访问的方法
		res.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
		// 设置IE浏览器
		res.setHeader("Access-Control-Allow-Headers",
				"Content-Type, Authorization, Accept,X-Requested-With");
		chain.doFilter(req, resp);
	}

	public void init(FilterConfig config) throws ServletException {

	}
}


7、web.xml配置过滤器

<!--配置过滤器 -->
	<filter>
		<filter-name>myFilter</filter-name>
		<filter-class>com.jsonp.filter.CrossDomainFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>myFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>


3、代码下载

http://pan.baidu.com/s/1jIpVfmQ

4、参考文章

1、http://kb.cnblogs.com/page/139725/

2、http://jiangzhenghua.iteye.com/blog/1221178

3、http://www.cnblogs.com/tengri/p/5565875.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值