duandong1963
duandong1963
2012-12-23 00:09
浏览 139

jQuery JSONP调用PHP后端:没有HTTP响应

Update IV / Current status: I've now confirmed trough another question that the character encoding of the file is fine and not the cause of the problem. I've also tested against another server and the error still persists. It does however work towards localhost. So to summarize: JSONP call works towards localhost, but when running against external domains the response from the server is empty (no header / no http response code). When copying the requested URL and inserting it directly in a browser, the output is correct with correct formating (utf-8 / json).

Fiddle: http://jsfiddle.net/5SJvp/1/

Update III: I'm now able to get it working succesfully on localhost. However, using the exact same code (both client and server) towards my production domain it still fails. The response from the server is "empty" meaning to say it returns no http status code.

Update II: After some more debugging I noticed that the response does not include an http status code. This probably is the cause of my problem? I assume this means there is something wrong server side, but I cannot for the life of me see where.

Update I: Snip from jQuery where to request seems to halt.

// Do send the request
// This may raise an exception which is actually
// handled in jQuery.ajax (so no try/catch here)
xhr.send( ( s.hasContent && s.data ) || null ); 

Params (from Firebug)

_   1356655864905
callback    jQuery18308375673194150332_1356655863817
p   0522
pl  12
s   false
secret  ##############################
u   request12341299

Request (from Firebug)

Accept  text/javascript, application/javascript, application/ecmascript, application/x-ecmascript, */*; q=0.01
Accept-Encoding gzip, deflate
Accept-Language nb-no,nb;q=0.9,no-no;q=0.8,no;q=0.6,nn-no;q=0.5,nn;q=0.4,en-us;q=0.3,en;q=0.1
Connection  keep-alive
Host    localhost:8888
Referer http://localhost:8888/popup.html
User-Agent  Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:17.0) Gecko/20100101 Firefox/17.0
X-Requested-With    XMLHttpRequest

Original question:

I'm struggling with what seems to be a common problem, but I've yet to find a solution. I'm trying to execute a very simple jsonp call using jQuery. The problem is that either a) nothing is happening or b), the response from the server is empty.

I've tried several different approaches, using both the $.ajax method and the $.getJSON method. Both produce the same faulty result. Using the code below nothing happens: Using the Chrome debugger I can see that it simply stops its execution halffway trough the method. However using Wireshark I can see that the client performs the three way handshake and thusly prepars to send data, it just fails to do that.

If I remove the callback=? it does execute, however the response is malformed (or at least, I think so since I can only see a response marked with a red line in Firebug).

$.ajax({
     url: "http://mydomain.com/asd.php", //"http://localhost:8888/index.php",
     dataType: 'jsonp',
     type: 'GET',
     data: {p:p, u:u, s:symbols, pl:pl, secret:secret},
     contentType: "application/json; charset=utf-8",
     async: false,
     success: function(data){
        console.log("What " + data.test); 
     }, 
     error: function(data){
         console.log("failed for some reason");
     }
 }); 

Server code ($callback = $_GET["callback"]

<?php header('content-type: application/json; charset=utf-8');
.
.
.
$data = array
(
    "message" => $message,
    "status" => $statuscode,
    "length" => strlen($message)        
);

echo $callback . '('.json_encode($data) .')';
exit;       
?>

Here is the server response with manually typed input.

funcName({"message":"!0b7(cb6Gv40","status":"OK","length":12})
  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

6条回答 默认 最新

  • dongshu7162
    dongshu7162 2013-01-01 04:34
    已采纳

    This will obviously NOT work if you did not set up your SSL certificates properly.

    This works properly when I transform the https to http: http://jsfiddle.net/eysEe/

    var u = "test";
    var p = 1234;
    var symbols = false;
    var pl = 16;
    var secret = "c68f39913f901f3ddf44c707357a7d70";
    
    $.ajax({
        url: "http://serve.pin2pass.com?index.php",
        dataType: 'jsonp',
        type: 'GET',
        data: {
            p: p,
            u: u,
            s: symbols,
            pl: pl,
            secret: secret
        },
        contentType: "application/json; charset=utf-8",
        async: false,
        success: function(data) {
            $('#test').text(data.message);
        },
        error: function(data) {
            $('#test').text("SDf");
        }
    });
    

    You can tell if you have bad SSL installation when "https://serve.pin2pass.com?index.php" leads to a risky page. Maybe you never intended to put it in https mode ?

    点赞 评论
  • dongnong3799
    dongnong3799 2012-12-23 00:30

    callback is the universal GET param for wrapper function name for the jsonp. When you use callback=? in jQuery request, jQuery will parse the ? into something else with a time stamp so it will be always be a unique value. The API server will wrap the json in this unique function name, and jQuery stores the name so it can use it to unwrap the response.

    Some API's are not flexible and require their own specific name in which case you can use the jsonpCallback option in either $.ajax or set it globally in $.ajaxSetup

    See $.ajax API docs: http://api.jquery.com/jQuery.ajax/

    点赞 评论
  • duanchique1196
    duanchique1196 2012-12-26 08:18

    It is hard to debug this without a jsfiddle/jsbin, so my best suggestion would be to try getting the request to work with fake, static data (just an empty JSON struct, {}, will do).

    It seems that the problem might lie in how you are using json_encode, since you write that when you add the callback=? param the response looks mangled. The suggested test will let you diagnose better where the issue lies.

    点赞 评论
  • drwghu6386
    drwghu6386 2012-12-26 17:18

    Starting from your code I've set it up locally and everything works as expected:

    test.php :

    <?php
    
    $callback = $_GET["callback"];
    
    $data = array
    (
        "message" => 'test',
        "status" => 200,
        "length" => strlen('test')        
    );
    
    echo $callback . '('.json_encode($data) .')';
    exit;
    

    test.html :

    <html>
    <head>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
    <script>
    $(document).ready(function(){
      $.getJSON("http://localhost/test.php?callback=?",
        {
          whatever: 1,},
        function(data) {
          alert("hmm");
        });
    });
    </script>
    </head>
    <body>
    </body>
    </html>
    

    Two things that could help you :

    1. Not putting the callback=? in your call fails because the JSON returned from your server is not valid JSON (due to the parenthesis around your json data). $.getJSON will silently fail in this case. If you want to see the error, use $.ajax instead.
    2. Your problem might come from the fact that you're apparently trying to use https here. In Chrome at least, making an AJAX request to an https URL with an invalid certificate (I assume your localhost or test domain doesn't have a valid certificate) just puts an error in the console. The browser never prompts with the "are you sure?" about the certificate.

    Hope it helps

    点赞 评论
  • douzizang7783
    douzizang7783 2012-12-31 11:19

    Hm, can you try using 'Fiddler' to debug the call? Perhaps that empty server response isn't that empty after all. Or maybe your server has some strange security settings, and checks the REFERRER header to block out external calls?

    If you can give a full url to your app I could test it for you =)

    点赞 评论
  • dsbgltg159136540
    dsbgltg159136540 2013-01-01 07:46

    So, with the new fiddle it was much easier to work. This is a working sample of your call-

    var u = "test";
    
    var p = 1234;
    var symbols = false;
    var pl = 16;
    var secret = "c68f39913f901f3ddf44c707357a7d70";
    
    $.ajax({
        url: "https://serve.pin2pass.com/index.php",
        dataType: 'jsonp',
        type: 'GET',
        data: {
            p: p,
            u: u,
            s: symbols,
            pl: pl,
            secret: secret
        },
        contentType: "application/json; charset=utf-8",
        aync:true,
        success: function(data) {
            $('#test').text(data.message);
        },
        error: function(data) {
            console.log("failed for some reason");
        }
    });​
    

    jsfiddle

    I hope I am not missing something here. The only change I had to do is in the request url, from

    https://serve.pin2pass.com?index.php
    

    to https://serve.pin2pass.com/index.php

    Hope this solves it.

    点赞 评论

相关推荐