jQuery的jsonp跨域是这么回事.

实现跨域请求的有iframe,img,script中的src属性.
那么jquery是如何解决跨域请求的呢?

一:
项目jsonp2中有个app.js文件,代码如下:

function app(json){
    alert(json[‘name‘]);
}

项目jsonp1中的index.html

<script type="text/javascript" src="http://127.0.0.1:8020/jsonp2/js/app.js"></script>
<script type="text/javascript">
    app({‘name‘:"guoyansi",‘age‘:25});
</script>

执行结果:
这里的app方法并没有申明,怎么就能调用了呢?
这里的第一个script出现了跨域请求,src指向的是jsonp2中的app.js
而在app.js中申明了app方法.
我们现在在火狐中查看index.html的源码,点开app.js的script

结论:从外部引入的app.js最终会被加载到浏览器中,渲染成这样:

<script type="text/javascript">
    function app(json){
    alert(json[‘name‘]);
}
</script>

根据上面的结论
我们如果利用script跨域向后台发送一个请求,
我们在后端返回一段js代码,前端不就可以调用了吗?
现在我们来验证假设.
我们用java为例子:
新建javaweb项目并且新建一个servlet,
这个servlet返回一个js代码;

package servelt;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class Jsonp2 extends HttpServlet {

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

        response.setContentType("text/javascript;charset=utf-8");//jsonp其实回写的就是一段javascript代码
        //或者:response.setContentType("text/plain;charset=utf-8");
        PrintWriter out = response.getWriter();
        out.print("app({‘name‘:‘思思博士‘,‘age‘:‘25‘})");
        out.flush();
        out.close();
    }

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

}

新建另外一个项目并且新建一个index.html页面

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title></title>
        <script type="text/javascript">
            function app(json){
                console.log(json);
            }
        </script>
        <script type="text/javascript" src="http://192.168.6.130:8080/jp/Jsonp2"></script>
    </head>
    <body>

    </body>
</html>

上面的第二个script直接执行了这个新的项目上的servlet.
并且最终被浏览器解析成如下格式:

<script type="text/javascript">
    app({‘name‘:‘思思博士‘,‘age‘:‘25‘})
</script>

index.html最终的页面变成这个样子:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title></title>
        <script type="text/javascript">
            function app(json){
                console.log(json);
            }
        </script>
        <script type="text/javascript">
            app({‘name‘:‘思思博士‘,‘age‘:‘25‘})
        </script>
    </head>
    <body>

    </body>
</html>

上面的代码我想大家都知道是怎么执行的了吧.
上面的代码返回的js代码的方法调用时时在服务器端写死的.我们也可以从客户顿指定要返回的反法调用名.
修改servlet:

package servelt;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class Jsonp2 extends HttpServlet {

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

        response.setContentType("text/javascript;charset=utf-8");//jsonp其实回写的就是一段javascript代码
        String appMethod=request.getParameter("appMethod");
        PrintWriter out = response.getWriter();
        out.print(appMethod+"({‘name‘:‘思思博士‘,‘age‘:‘25‘})");
        out.flush();
        out.close();
    }

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

}

在客户端指定要服务器要返回的js方法,添加appMethod参数,修改index.html.

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title></title>
        <script type="text/javascript">
            function app(json){
                console.log(json);
            }
        </script>
        <script type="text/javascript" src="http://192.168.6.130:8080/jp/Jsonp2?appMethod=app"></script>
    </head>
    <body>

    </body>
</html>

上面的例子都是返回一段可执行的js代码,来调用本地的方法.
我们对上面的例子进行封装.java代码保持不变.

(function($){
    $.gys=function(opt){
        var scriptCode=(new Date()).getTime();
        //拼接script标签
        var html="<";
        html+="script id=‘script"+scriptCode+"‘ type=‘text/javascript‘ src=‘"+opt.src+"?"+opt.callbackName+"="+opt.callback+"‘>";
        html+="<";
        html+"/script>";
        //申明一个全局的方法变量供远程返回的js方法的调用,方法名有callback指定
        window[opt.callback]=function(json){
            opt.success(json);//调用当前参数的方法
            $("#script"+scriptCode).remove();//删除script标签
        }
        $("head").append(html);//插入script标签
    }
})(jQuery);

调用:

$(function(){
    $.gys({
        callbackName:"appMethod",
        callback:"app",
        src:"http://192.168.6.130:8080/jp/Jsonp2",
        success:function(data){
            console.log(data);
        }
    });
});

看到这个有没有觉得和jquery的jsonp有点像了啊.
我们现在看看jquery的jsonp.
jsonp其实用的就是上面的原理

我们看看jquery的jsonp用法.

$.ajax({
    type:"get",//jsonp只能触发get请求
    url:""//跨域url
    dataType:"jsonp",
    jsonp:"",//对应上面封装的callbackName
    jsonpCallback:"",//对应上面封装的callback
    data:{},//提交参数
    beforeSend:function(){
        //jsonp 方式此方法不被触发。原因是这里已经不是ajax事件了.
    },
    success:funciton(data){
        //参数jsonpCallback的方法调用这里的success
    },
    error:function(){
        //这里不是ajax了,所以这个方法也不会触发.
    }
});

jquery中把jsonp和ajax整合在一起了具有一定的迷惑性,ajax是不具有跨域请求的,
另外jsonp使用的核心也不是ajax的xmlhttprequest,而是script的http请求(脚本注入的行为).
另外这样的jsonp是不具有post请求的.
$.getJSON()和$.getScript()都是jsonp的高级封装.

时间: 2024-08-27 11:56:41

jQuery的jsonp跨域是这么回事.的相关文章

JQuery+ajax+jsonp 跨域访问

Jsonp(JSON with Padding)是资料格式 json 的一种“使用模式”,可以让网页从别的网域获取资料. 关于Jsonp更详细的资料请参考http://baike.baidu.com/view/2131174.htm,下面给出例子: 一.客户端 Html代码   <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.

jquery ajax jsonp跨域调用实例代码

今天研究了AJAX使用JSONP进行跨域调用的方法,发现使用GET方式和POST方式都可以进行跨域调用,这里简单分享下,方便需要的朋友 客户端代码 复制代码 代码如下: <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="WebApp.WebForm1" %><!DOCTYPE html P

用jQuery实现jsonp跨域

跨域的安全限制都是指浏览器端来说的,服务器端是不存在的跨域安全限制的. 所以通过本机服务器端通过类似httpclient方式完成"跨域访问"的工作,然后在浏览器端用AJAX获取本机服务器端"跨域访问"对应的url,来间接的完成跨域访问也是可以的但很显然开发量比较大,但限制也很少,很多widget开放平台server端(如sohu博客开放平台)其实就在这么搞的,不在本次讨论范围. 要讨论的是浏览器端的真正跨域访问,推荐的是目前jQuer$.ajax()支持get方式的

jquery使用jsonp跨域请求代码示例

HTML 部分 文件名:test.html 1 <meta charset="utf-8"> 2 <script src="http://cdn.bootcss.com/jquery/1.11.1/jquery.min.js"></script> 3 <script> 4 function jsonpCallback(){ 5 alert('jsonpCallback'); 6 } 7 $(document).read

jquery下jsonp跨域请求

客户端js代码: $(function(){ $.ajax( { type:'GET', url : "../php/getGIS.php?id=[50010000001200000001,50010000001200000003]", dataType : 'jsonp', jsonp:"jsoncallback", success : function(data) { alert( data ); }, error : function() { alert('f

JS的jsonp是什么?5分钟学会jsonp跨域请求

一.jsonp是什么? jsonp是解决跨域请求的一种技术.浏览器为了防止CSRF攻击会采用同源策略(协议/主机/端口均相同)限制,对非同源发起http请求(即跨域请求)会被浏览器阻止. 二.jsonp跨域请求的原理? script标签的src属性不受同源策略限制,用此方式对非同源服务器请求资源,返回的JS代码会调用指定的函数,携带的参数就是所需的数据,这样就完成了跨域请求. 三.原生JS的jsonp跨域请求: 首先声明一个处理返回数据的函数,返回的JS代码会调用此函数: function do

jQuery和java后台的jsonp跨域问题

Jsonp原理: ajax本身是不可以跨域的,通过产生一个script标签来实现跨域.因为script标签的src属性是没有跨域的限制的.其实设置了dataType: 'jsonp'后,$.ajax方法就和ajax XmlHttpRequest没什么关系了,取而代之的则是JSONP协议.JSONP是一个非官方的协议,它允许在服务器端集成Script tags返回至客户端,通过javascript callback的形式实现跨域访问. JSONP是一种脚本注入(Script Injection)行

jquery Jsonp 跨域访问

$(function () { $.ajax({ url: 'http://ihisuns.vicp.cc:8765/PcClient.aspx', data: { "ModuleName": "MiXinDialogue", "MethodName": "GetMiXinDialogue", "Id": "1" }, dataType: "jsonp", jsonp

跨域问题相关知识详解(原生js和jquery两种方法实现jsonp跨域)

1.同源策略 同源策略(Same origin policy),它是由Netscape提出的一个著名的安全策略.同源策略是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响.可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现,现在所有支持JavaScript 的浏览器都会使用这个策略. 所谓同源,就是指两个页面具有相同的协议,主机(也常说域名),端口,三个要素缺一不可. 所谓同源策略,指的是浏览器对不同源的脚本或者文本的访问