JavaScript JSONP跨域请求原理及jQuery与原生实现示例
浏览器基于安全考虑执行同源策略,限制了AJAX请求的跨域访问。JSONP(JSON with Padding)利用不受同源策略限制的 <script> 标签加载外部脚本,并通过预先定义的回调函数处理返回数据。本文将通过原理拆解与代码对比,展示如何快速实现JSONP跨域调用。
JSONP协议核心原理
受同源策略约束,标准的 XmlHttpRequest 对象只能请求当前源(域名、协议、端口一致)的资源。JSONP通过引入HTML的动态脚本注入机制绕过此限制:
- 触发请求: 在页面中动态创建或修改一个
<script>元素,将其src属性指向外部服务器的接口地址。 - 服务端封装: 服务器接收请求后,获取指定的回调函数名,将JSON格式的数据包裹在该函数调用中(如
callbackName({"data": "value"}))并返回。 - 执行结果: 浏览器加载这段脚本,自动执行传入的回调函数,从而完成数据的解析与应用。
安全警示: JSONP本质上属于脚本注入行为,若服务端未对输入参数进行严格过滤,可能面临跨站脚本攻击(XSS)风险。
实战:基于jQuery的实现
在现代开发中,通常优先使用库函数简化逻辑。以下是基于jQuery的Ajax异步请求实现,适用于子域名调用主域名的场景。
第一步:配置客户端请求
入口:HTML页面的Script标签。动作:调用 $.ajax 方法指定跨域类型。
<!DOCTYPE html>
<html>
<head>
<title>JSONP测试例子</title>
<!-- 引入jQuery -->
<script src="jquery.min.js"></script>
<script type="text/javascript">
jQuery(document).ready(function(){
$.ajax({
type: "get",
url: "http://www.other-domain.com/api/jsonp.php",
dataType: "jsonp", // 指定为jsonp类型
jsonp: "callback", // 传递给服务端的参数名
jsonpCallback:"feedBackState", // 自定义回调函数名
success: function(data){
var $ul = $("<ul></ul>");
// 遍历数据渲染列表
$.each(data,function(i,v){
$("<li/>").text(v["id"] + " " + v["name"]).appendTo($ul)
});
$("#remote").append($ul);
},
error: function(){
alert('fail');
}
});
});
</script>
</head>
<body>
远程数据如下:<br/>
<div id="remote"></div>
</body>
</html>
第二步:配置服务端响应(PHP示例)
目的:将原始JSON数组包装在回调函数名中输出。
<?php
// 1. 获取客户端传递的回调函数名
$callbackName = $_REQUEST["callback"];
// 2. 准备要传输的JSON数据
$data = '[{"id":"1","name":"测试项一"},{"id":"2","name":"测试项二"}]';
// 3. 组合成合法的JS代码并输出
echo $callbackName . "(" . $data . ")";
?>
进阶:原生JavaScript手动实现
若不依赖第三方库,需要手动管理DOM节点的创建与服务端交互流程。
第三步:编写原生脚本控制逻辑
入口:页面底部的 <script> 块。定义全局回调函数并在点击时发起请求。
<script type="text/javascript">
// 1. 预处理回调函数
function OnJSONPServerResponse(data) {
var $ul = $("<ul></ul>");
$.each(data, function(i,v){
$("<li/>").text(v["id"] + " " + v["name"]).appendTo($ul)
});
$("#remote").append($ul);
}
// 2. 发起请求封装
function CallJSONPServer(url) {
// 检查是否已存在该节点的引用(用于复用或更新)
var oldScript = document.getElementById("json_script_node");
if(oldScript){
oldScript.setAttribute("src", url);
return;
}
// 创建新的 script 节点
var script = document.createElement("script");
script.setAttribute("type", "text/javascript");
script.setAttribute("src", url); // 必须包含回调函数参数
script.setAttribute("id", "json_script_node");
document.body.appendChild(script);
}
</script>
第四步:触发按钮配置
<input type="button" value="点击获取远程数据" onclick="CallJSONPServer('http://www.other-domain.com/api/original.php?callback=OnJSONPServerResponse')" />
<div id="remote"></div>
关键兼容性与排错指南
在实际跨域通信中,常遇到字符集不一致或路径拼接错误导致的请求失败,请对照以下参数进行调整:
- 编码一致性: jQuery默认使用UTF-8发送参数。确保服务端输出的JSON字符串编码也为UTF-8,否则中文数据会出现乱码,需在PHP中使用
mb_convert_encoding进行转换。 - URL路由规范: 服务端接口地址建议保留完整文件后缀。例如使用
/index.php?act=add而非仅参数部分?act=add,这在部分旧版服务器环境下可避免路由匹配异常。
以上就是JSONP跨域原理与多语言实现的详细内容,更多关于前端Ajax技巧的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









