JavaScript JSONP跨域请求原理及jQuery与原生实现示例

阿麦
阿麦
发布时间:2026-10-14 | 5人浏览过
原创

浏览器基于安全考虑执行同源策略,限制了AJAX请求的跨域访问。JSONP(JSON with Padding)利用不受同源策略限制的 <script> 标签加载外部脚本,并通过预先定义的回调函数处理返回数据。本文将通过原理拆解与代码对比,展示如何快速实现JSONP跨域调用。

JSONP协议核心原理

受同源策略约束,标准的 XmlHttpRequest 对象只能请求当前源(域名、协议、端口一致)的资源。JSONP通过引入HTML的动态脚本注入机制绕过此限制:

  1. 触发请求: 在页面中动态创建或修改一个 <script> 元素,将其 src 属性指向外部服务器的接口地址。
  2. 服务端封装: 服务器接收请求后,获取指定的回调函数名,将JSON格式的数据包裹在该函数调用中(如 callbackName({"data": "value"}))并返回。
  3. 执行结果: 浏览器加载这段脚本,自动执行传入的回调函数,从而完成数据的解析与应用。

安全警示: 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技巧的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表