jsonp跨域请求

本文介绍了JSONP的概念及其工作原理,并通过一个具体的实例展示了如何在Java Struts2环境中结合ajax和jQuery实现JSONP进行跨域数据请求。

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

一,什么是jsonp?

        大家在使用ajax的过程中可能都遇到过相似的问题,比如js代码写的都正确,后台代码也没问题,可是ajax就是接收不到返回的数据,其实这是由于 同源策略造成的。同源策略的定义是:
        1,同源策略,是由Netscape提出的一个著名的安全策略。现在所有支持JavaScript 的浏览器都会使用这个策略。
        2,所谓同源是指《域名,协议,端口》均相同。
        如当一个浏览器的两个tab页中分别打开来 百度和谷歌的页面,当浏览器的百度tab页执行一个脚本的时候会检查这个脚本是属于哪个页面的,即检查是否同源,只有和百度同源的脚本才会被执行。一般来说位于 server1.example.com 的网页无法与不是 server1.example.com的服务器沟通,如你电脑上的的一个html页面中,无法通过脚本或ajax获取到你另外一台电脑上的数据。如下图:
       但是HTML 的<script> 元素是一个例外,利用 <script> 元素的开放策略,网页可以得到从其他来源动态产生的 JSON 资料,而这种使用模式就是所谓的 JSONP。用 JSONP 抓到的资料并不是 JSON,而是任意的JavaScript,用 JavaScript 直译器执行而不是用 JSON 解析器解析。
       例如使用jquery调用百度地图的一个地理位置查询接口(根据坐标查询地址),就是使用的jsonp:
$.getScript("http://api.map.baidu.com/geocoder/v2/?ak=771719E5AA0bf28de657530a9b4d3b23&callback=handleModify&location=121.226574,25.145863&output=json");
然后我们可以自定义一个handleModify函数来接收百度返回的地理位置信息,测试说明正常访问到了百度的接口,并接受到了返回的数据,这就是jsonp突破同源策略的一个例子。

二,jsonp原理

【非官方易理解简介】
包括IE6在内的大多浏览器支持的标准跨域数据访问方式。
核心思想是利用JS标签里面的跨域特性进行跨域数据访问,在JS标签里面存在的是一个跨域的URL,实际执行的时候通过这个URL获得一段字符串,这段返回的字符串必须是一个合法的JS调用,通过EVAL这个字符串来完成对获得的数据的处理。
大多JS框架都支持一个包装后的JSONP实现,如jQuery,extjs等。
【以下是官方内容】
JSONP是一个非官方的协议,它允许在服务器端集成Script tags返回至客户端,通过javascript callback的形式实现跨域访问(这仅仅是JSONP简单的实现形式)。

三,java+struts2+ajax+jQuery+jsonp的一个例子

1,s代码
$.getJSON("http://192.168.1.116:8080/test?on=1&jsonpcallback=?",function(data){
	alert(data.status);
});
其中的jsonpcallback是任意的,要在action中接收的。
$.ajax也可:
$.ajax({
	url:"http://192.168.1.116:8080/test",
	type:"GET",
	dataType:"jsonp",
	jsonp:"jsonpcallback",
	data:{"on":1},
	success:function(data){
		handleResult(data.status);
	}
});
type不能为post
2,java代码:
package com.rick.store.test;

public class TestAction {
	private int on;
	public void setOn(int on) {
		this.on = on;
	}
	private String jsonpcallback;
	public void setJsonpcallback(String jsonpcallback) {
		this.jsonpcallback = jsonpcallback;
	}
	
	private int status; 
	public int getStatus() {
		return status;
	}
	public String execute() throws JSONException{
		if(on!=0){
			switch (on) {
				case 1:
					status=11;
					break;
				case 2:
					status=21;
					break;
				case 3:
					status=31;
					break;
				case 4:
					status=41;
					break;
				default:
					break;
			}
		}
		return "success";
	}
}
jsonpcallback不要提供getter方法
3,struts.xml配置
<action name="test" class="com.rick.store.test.TestAction">
	<result type="json">
    		<param name="callbackParameter">jsonpcallback</param>
    	</result>
</action>
callbackParameter是struts提供的对jsonp支持的一种格式,如下
root:只包含xx对象
excludeProperties  :除了xx之外的集合
includeProperties : 包含xx的集合
wrapPrefix :json结果开头添加xx(比如<paramname="wrapPrefix">[</param>)
wrapSuffix :同上,只不过是结尾
ignoreHierarchy :转化时是否忽略继承关系true/false
enumAsBean : 是否将枚举当做一个bean处理
enableGZIP :是否支持gzip压缩输出
noCache :是否缓存
excludeNullProperties : 是否转化输出 null值
statusCode :设置响应代号比如 304
callbackParameter : JSONP跨域访问的回调设置
contentType : 输出类型
jsonpcallback不需要getter方法,否侧返回的值就不一样了,大家可以自己测试
4,运行结果:



### JSONP 请求实现方法及原理 JSONP(JSON with Padding)是一种通过 `<script>` 标签的 `src` 属性来绕过浏览器同源策略限制的方法,从而实现在不同名之间传输数据的功能。其核心思想是利用 `<script>` 标签可以加载外部资源且不受同源策略约束这一特性。 #### 原理说明 当客户端发起一个请求时,由于 XMLHttpRequest 受限于同源策略无法直接访问其他上的资源,而 `<script>` 标签则可以通过设置 `src` 属性自由加载来自任何名下的 JavaScript 文件。因此,在 JSONP 中,客户端会在页面中动态创建一个 `<script>` 标签,并将其指向目标服务器的一个 URL 地址,同时附加一个回调函数名称作为查询参数[^1]。服务器接收到此请求后,会返回一段以指定回调函数包裹的数据形式的 JavaScript 代码。这段代码会被立即执行,进而调用预先定义好的回调函数并将所需数据传递进去[^2]。 #### 实现过程详解 以下是具体的操作流程: 1. **客户端准备阶段** 客户端先定义好用于接收响应数据的全局回调函数。 ```javascript function handleResponse(data) { console.log('Received data:', data); } ``` 2. **构建并插入 script 元素** 动态生成一个新的 `<script>` 元素,设定其 `src` 属性为目标接口地址加上必要的查询字符串(通常包含 callback 参数),最后将该元素添加至 DOM 结构中的合适位置(如 body 的子节点列表末端)。 ```javascript var script = document.createElement('script'); script.src = 'https://example.com/api?callback=handleResponse'; document.body.appendChild(script); ``` 3. **服务端配合处理** 当服务器接获带有特定 callback 名称字段的 HTTP 请求之后,应该按照约定格式构造回应内容——即将实际业务逻辑所产生的结果序列化成合法 JSON 字符串后再嵌套进由前述 callback 所指示的那个函数体内形成最终输出文本流送回前端展示层面上去渲染呈现出来供后续操作使用[^4]。 ```javascript // Example server-side pseudo-code (Node.js/Express-like syntax) app.get('/api', (req, res) => { const data = { key: 'value' }; const jsonResponse = JSON.stringify(data); const callbackFunctionName = req.query.callback || 'jsonpCallback'; res.send(`${callbackFunctionName}(${jsonResponse})`); }); ``` 以上便是整个基于 JSONP 技术完成的一次典型交互全过程描述总结概述完毕如下所示[^3]。 ```javascript // Client Side Code Summary function jsonpRequest(url, callbackName){ let scriptTag=document.createElement("script"); window[callbackName]=function(responseData){console.log(responseData);delete window[callbackName];}; scriptTag.src=`${url}&callback=${callbackName}`; document.head.append(scriptTag); } ``` ### 注意事项 尽管 JSONP 提供了一种简单有效的解决方案来进行通信,但它也存在一些固有的缺陷需要注意: - **安全性隐患**: 因为它依赖注入任意第三方站点提供的脚本来运行环境当中所以可能存在恶意代码攻击风险; - **仅支持 GET 方法**: 不允许像常规 AJAX 那样灵活运用多种类型的 HTTP Method 如 POST PUT DELETE 等等[^2].
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值