1

So, essentially I have this Javascript which interprets the JSON from my php code. It works great on the local server, however, when I try to move the script to a different server it will not work. I have added the

<?php header("Access-Control-Allow-Origin: *"); ?>

also i've declared my database connection as global within my PHP function.

I'm confused as to why these solutions aren't working.. Also, I understand some of the script is iffy, but I'm only interested in figuring out why its not working from different servers.

<script type="text/javascript">
$("document").ready(function(){
  $(".sendText").submit(function(){
    $("#sendButton").prop("disabled",true);
    $(".errors").html("");
    $(".success").html("");
    var data = {
      "action": "test"
    };
    data = $(this).serialize() + "&" + $.param(data);
    $.ajax({
      type: "POST",
      dataType: "jsonp",  //new edit
      url: "http://myurl.com/testing/jsonpost.php?callback=test",  //new edit
      data: data,
      success: function(data) {
        if(data["success"]=="yes") {
        $(".success").html("Message Sent!");
        $(".formContainer").html("" + data["json"] + "");
        }
        else {
        if(document.getElementById("sendButton").disabled = true){ document.getElementById("sendButton").disabled = false; }
        $(".errors").html("" + data["errors"] + "");
        }
      }
    });
    return false;
  });
});
</script>

Some Info when I look at the web console from firebug:

Access-Control-Allow-Orig...    *
Connection  Keep-Alive
Content-Length  0
Content-Type    application/json
Date    Wed, 24 Sep 2014 04:22:57 GMT
Keep-Alive  timeout=5, max=100
Server  Apache/2.2.27 (Unix) mod_ssl/2.2.27 OpenSSL/1.0.1e-fips DAV/2 mod_bwlimited/1.4
X-Powered-By    PHP/5.4.29

Looks like it is communicating with server but not able to interpret data? thoughts?

Also, this error comes up in the console from the remote server but not when I run on local server:

SyntaxError {stack: (...), message: "Unexpected end of input"}message: "Unexpected end of input"stack: (...)
Object {readyState: 4, getResponseHeader: function, getAllResponseHeaders: function, setRequestHeader: function, overrideMimeType: function…
parsererror 

The PHP code is pretty long (and I prefer not to release all of it) - however here is the shortened version:

<?php
header("Access-Control-Allow-Origin: *");
header('Content-Type: application/json');
require "../database/db.php";

if (is_ajax()) {
  if (isset($_POST["action"]) && !empty($_POST["action"])) { //Checks if action value exists
    $action = $_POST["action"];
    switch($action) { //Switch case for value of action
      case "test": test_function(); break;
    }
  }
}

//Function to check if the request is an AJAX request
function is_ajax() {
  return isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest';
}

function test_function(){
$c="1";
global $con;

  $return = $_POST; //to reference post

$content=$return["content"];

//see if content is 140 characters or less
if(strlen($content)>140){ $c="0"; $lerror="<li>Your message must be 140 characters or less in length!</li>"; }



if($c=="0"){  //doesnt pass validation
$return["success"]="no";
$return["errors"]="$lerror";
}

if($c!="0"){ //passes validation
$return["success"]="yes";
}
if(isset($_GET['callback'])){  //jsonp edit
$return["json"] = json_encode($return);
echo $_GET['callback']."(".json_encode($return).")"; //jsonp edit
}

}

Also after converting to JSONP on remote server - get error -

"jQuery111006159528985153884_1411663761720 was not called"
pkjayk
  • 25
  • 7
  • what does the console say? besides some wrong parts of your code, you need tell us the errors – Kevin Sep 24 '14 at 03:46
  • What content-type is returned for the response with JSON? – Cheery Sep 24 '14 at 03:47
  • Can you post the error message from your browser console? Thnx – William Francis Gomes Sep 24 '14 at 03:49
  • If you are using cross domain I think you need to use jsonp – andrex Sep 24 '14 at 03:51
  • @andrex : he is setting the `Access-Control-Allow-Origin` headers. that should work. – Mithun Satheesh Sep 24 '14 at 03:52
  • @mithunsatheesh but that's on the server side right?, should the call also need to cross-domain call? It's better is we can see the console errors if there is something. – andrex Sep 24 '14 at 03:53
  • @andrex : jquery has crossDomain propery in ajax call. it will be by default true for cross domain calls. So no need to set. – Mithun Satheesh Sep 24 '14 at 03:55
  • @andrex Also curious, how would I convert this code to jsonp? – pkjayk Sep 24 '14 at 04:05
  • @user4064479 : do you mind checking the browser console and telling us the errors you see there? – Mithun Satheesh Sep 24 '14 at 04:07
  • @mithunsatheesh all that comes up: "The character encoding of the HTML document was not declared...", I know that isn't related to the problem though -- – pkjayk Sep 24 '14 at 04:15
  • @user4064479 jsonp is just another of the ajax return datatype, plus you need to add callback handlers for it in your php. But per mithunsatheesh mentioned ajax is already crossdomain enable. It's all documented in here http://api.jquery.com/jquery.ajax/ – andrex Sep 24 '14 at 04:27

2 Answers2

1

When dealing with jQuery AJAX using a data type of JSON, any notice, warning or error produced by the server side script will cause issues. The reason being is the outputted PHP errors break the JSON encoding that jQuery is expecting.

I suspect the two environments are not identical, perhaps a different PHP version, missing PHP extension or different settings in the php.ini file.

The best thing to do is to use the provided jQuery AJAX error callback to console log any errors allowing you to essentially troubleshoot any issues being thrown by the server side script.

!!! EDIT 3 !!!

Client Code

$.ajax({
    type: "POST",
    dataType: "json",
    url: "http://myurl.com/jsonpost.php", 
    data: data,
    success: function(response) {
        console.log(response);
    },
    error: function(xhr, status, error) {
       console.log(xhr);
       console.log(status);
       console.log(error);
    }
});

Server Side Code

header("Access-Control-Allow-Origin: *");
header('Content-Type: application/json');

echo json_encode(array('success' => 'yes'));

Using this bare bones version of your code I can successfully make a cross domain request and console log the response. If you implement this code and it still does not work there is something else at play at the server and/or network level.

Brian Bolli
  • 1,873
  • 1
  • 12
  • 14
  • "SyntaxError {stack: (...), message: "Unexpected end of input"}message: "Unexpected end of input"stack: (...)" - this is an error I get. – pkjayk Sep 24 '14 at 18:30
  • Edited my answer with some more specific regarding the error object. Lots of information in it but in this instance, we're looking for one specific property. – Brian Bolli Sep 24 '14 at 19:47
  • responseText: "" - no response text at all. – pkjayk Sep 24 '14 at 19:52
  • check edits, server side code was issue and got working locally with edits I made. – Brian Bolli Sep 24 '14 at 20:39
  • no luck with that - this code was already working locally for me.. I just want it to work cross-domain – pkjayk Sep 24 '14 at 23:45
  • Yes, I know. You can execute a cross domain request from a local development environment. Which I was able to do with the code above. Try changing your dataType variable to "text" and see if that works. – Brian Bolli Sep 25 '14 at 00:19
  • that worked to communicate with server - but response comes as "undefined" – pkjayk Sep 25 '14 at 16:22
  • Did you add the code from my EDIT 2 entry? You code didn't set a default value for the $c variable. Meaning, if the $content length is not greater then zero it is never declared. This results in both the following if statements against the $c variable to fail, which in turn means the $return array is never set. In the beginning of your test_function() add $c = "1" and that should solve it. – Brian Bolli Sep 25 '14 at 16:43
  • yes, sorry - i added that awhile ago but forgot to update on here. – pkjayk Sep 25 '14 at 16:47
  • Just to confirm whether or not the core issue of successfully getting a response with a cross-domain request, echo out a dummy JSON string like {"test":"successfull"} and see if you get the data. I still suspect logic or workflow issues for the undefined response and this will help us confirm. – Brian Bolli Sep 25 '14 at 17:40
  • I could get a response on local with dummy json string but not remote – pkjayk Sep 25 '14 at 18:20
  • Wait, four comments ago you said you got a server response with undefined. Was that local? Regardless, see my last edit with bare bones code which works cross-domain for me. If this still doesn't work this isn't an issue with your code. – Brian Bolli Sep 25 '14 at 18:29
  • Ok - at first I was getting an error saying data wasn't defined - I removed data and it works cross-domain. looks like it's my code. I'm going to build it up from bare bones and see if I can get it to work.. – pkjayk Sep 25 '14 at 19:42
0

You can make AJAX calls to a backend API, it needs to return JSONP format and not just JSON, otherwise you can get error. This is due to same origin policy:

https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy.

This discussion may be helpful to understand JSONP:

Can anyone explain what JSONP is, in layman terms?

However, one alternative is disable the security of Google Chrome browser, then it will work. But this is not a solution. It is better to use JSonP format.

Community
  • 1
  • 1
ajitksharma
  • 4,523
  • 2
  • 21
  • 40