XMLHttpRequest "total" returns 0 when fetching JSON - php

MORE EDITS
After testing the code on several browsers, it appears that I am only able to get the XMLHttpRequest.lengthComputable to be true on FireFox, thus giving me a download percentage. It returns false for both Chrome and Safari... any ideas to solve this? I have included the header("Access-Control-Allow-Origin: *"); tag at the top of my PHP script.
EDIT
Alright, with the help from the comments, I have my PHP sending a Content-Length however, the evt.total is still returning a 0. Any idea?
After further testing, it appears that evt.lengthComputable is set to false - therefore it is ignoring evt.total... now I need to find out why that is.
Here is the data in the Headers
Request Method:GET
Status Code:200 OK
Request Headers
Accept:*/*
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
Host:(deleted data here for confidential reasons)
Origin:(deleted data here for confidential reasons)
Referer:(deleted data here for confidential reasons)
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.115 Safari/537.36
Response Headers
Access-Control-Allow-Origin:*
Connection:keep-alive
Content-Encoding:gzip
Content-Length:1914150
Content-Type:application/json
Date:Wed, 25 Feb 2015 22:38:22 GMT
Server:Apache
Vary:Accept-Encoding
ORIGINAL POST
Maybe this is a dumb question, but here it is...
I'm working on a private PhoneGap app which is essentially a company directory. When the app first starts, it detects that the stored JSON is empty has not yet been downloaded and prompts the user to start the download.
I obtain the JSON data using an AJAX call. The JSON is generated by PHP on our server that queries the database, builds the array, then json_encode and echos the output.
The data transfers to our app and everything is working nicely, however, I'd like to build a "Progress Meter" for the download which requires me to know exactly how large the data being sent over is. I know PHP has some ways to get file size of certain files such as filesize($somefile), but how would I be able to measure the byte size of the JSON data? Can this even be done? Here is some of the code I am using...
PHP Building The JSON Data
while(...fetch the data) {
$output[] =
array (
"id" => $row['id'],
"firstname" => $row['firstname'],
"lastname" => $row['lastname'],
"jobtitle" => $row['jobtitle'],
"phone" => $row['phone'],
"cell" => $row['cell'],
"email" => $row['email'],
"department" => $row['department'],
"sub" => $row['sub'],
"image" => $row['image']
);
}
echo json_encode($output);
Here I am getting the JSON with AJAX: (I am using Framework7 - hence the $$)
$$.ajax({
url: "my-site-here.php",
dataType: "json",
beforeSend: function(XMLHttpRequest) {
//Download Progress Attempt (Found By Googling)
XMLHttpRequest.addEventListener("progress", function(evt){
//console.log("Downloaded: " + evt.loaded) <-- THIS IS WORKING;
//console.log("Total: " + evt.total) <-- THIS RETURNS 0;
var percentComplete = evt.loaded / evt.total;
console.log(percentComplete);
if (evt.lengthComputable) {
var percentComplete = evt.loaded / evt.total;
console.log(percentComplete);
} else {
// console.log("Cannot Compute File Size"); <-- THIS IS WHAT OUTPUTS
}
}, false);
},
success: function(json) {
// GETS DATA, RENDERS IT
}
});
Thanks in advance for some insight!

I found this solution here: https://stackoverflow.com/a/24073356/2163226.
All I had to do was edit my .htaccess file to expose the Content-Length header.
Now everything is working as intended!
Thank you all for the help and suggestions!

EDIT - Misunderstood the request process.

Related

MSXML2.XMLHTTP send data to PHP script

I have been looking into an option to send data read from an attached file in an Outlook message, directly to a PHP script that will then insert the date in a nice MySQL database.
The extraction of the file and the splitting of data all ok, but here is the trick...
From the internet (here) I found a nice post by Jeremy Slade who has managed to send some data to a cgi scipt, all good.
So, clever as I thought I was, I thought I could re-write this into dealing with a PHP script.
But then the works stopped.
I have shortened the code to below snippet;
Sub TestURL()
Set xhr = CreateObject("MSXML2.XMLHTTP")
URL = "http://somedomain.com/php/test.php"
data = "someVariable=Test"
With xhr
.Open "POST", URL, False
.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
.Send data
End With
End Sub
This should, in theory, open a MSXML2.XMLHTTP request at the given URL and send whatever data with it to the script.
Funny enough, the script is called, but no data is passed ?
I've tried setting the PHP script to both $_GET and $_POST for the [someVariable] element, yet on neither is there any response ?
When I set the PHP to $_GET I matched the VBA MSXML2.XMLHTTP object to "GET" as well and vice versa...
I've tried passing the 'data' variable as argument to the 'function' .send by including it in brackets
i.e.
.send (data)
But this doesn't work either...
I'm a bit at a loss, because the script is called, a dataline is added to the table yet there is not an actual transfer of the 'sent' data ??
I've tried connecting the data string to the URL that is passed to the HTTP object, essentially passing a 'GET' URL to the HTTP object.
i.e.
URL = URL & "?" & data
but to no avail...:-(
The php script works in itself properly, if I pass data directly from the browser
i.e.
http://somedomain.com/php/test.php?someVariable=Test
the data is correctly added and the variable is read...
Can some more enlightened spirits guide me in the right direction ?
20141016 ********** UPDATE **********
Ok, when digging into stuff I found there is also an option to refer to the XmlHttp object as "Microsoft.XmlHttp" ?
Funny enough, when setting the object like that,
i.e.
Set xhr = CreateObject("Microsoft.XMLHTTP")
The code works and the data is added to the table and the .responsText is a success message.
Yet if I return to the original code, I get a PHP error message that tells me that there is an error in my PHP syntax ?? This would imply that the actual 'data' that is being send differs between using "MSXML2.XMLHTTP" and using "Microsoft.XMLHTTP" ???
Have tried to dig out the difference between the two from internet but can't find any post that provides me with a full understanding of the subject ?
Despite the fact that my code now works, I still have the bothering question of not understanding the difference between the two and would appreciate a reply from someone who does :-) As I now have a code that works, but not an understanding of why it works...:-)
Or mroeover not an understanding of why the "MSXML2" option does NOT work...
Much appreciated,
Kindest regards
Martijn
This is not exactly an answer but more like a comment as I lack enough reputation to comment.
The issue can be analyzed using Fiddler which provides details of the requests and responses. I checked the same code as yours in my system with both MSXML2.XMLHTTP and Mirosoft.XMLHTTP objects and found no difference in teh requests. Both of them passed the POST request body containing someVariable=Test to the URL http://somedomain.com/php/test.php.
Here is the raw POST request in both cases:
POST http://somedomain.com/php/test.php HTTP/1.1
Accept: */*
Accept-Language: en-us
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; Trident/5.0; SLCC1; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729; .NET4.0C; .NET4.0E; MS-RTC LM 8)
Host: somedomain.com
Content-Length: 17
Proxy-Connection: Keep-Alive
Pragma: no-cache
someVariable=Test
And the response from the sample URL provided:
HTTP/1.1 405 Method Not Allowed
Server: nginx/1.7.6
Date: Thu, 08 Jan 2015 15:23:58 GMT
Content-Type: text/html
via: HTTP/1.1 proxy226
Connection: close
<html>
<head><title>405 Not Allowed</title></head>
<body bgcolor="white">
<center><h1>405 Not Allowed</h1></center>
<hr><center>nginx/1.7.6</center>
</body>
</html>
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
One question here would be whether the web server in question is expecting further data to be passed by the way of headers (User-Agent, Referer, Cookies etc) or as part of the request body (may be further input elements that are part of the webform)?

Ajax response is JSON on server and STRING on local computer with CakePHP, why?

locally and on the server, I get different results with the same code.
Locally my results arrive as string, while on the server, the same code returns JSON object. Can anybody tell me why?
The javascript:
$.post(
url, // Various urls of type '/users/add_secondary_email_ajax'
data,
function(res){
if (typeof(res.success)=='undefined'){
ModalManager.update_body_html(res);
}else{
callback_success(res);
}
}
);
The CakePHP:
$this->autoRender = false;
$this->RequestHandler->respondAs('json');
echo json_encode( array('success'=>true) ); // this arrives as string locally
return;
I also had this working on my other computer, but not this one. Could it be some PHP settings?
Both computers have the same versions of Browser & CakePHP version (2.2.3).
I see differences in PHP and Apache versions. Could be settings also, but I don't know where to look.
Header On Broken Computer:
Request URL:localhost/alert_subscribers/subscribe_ajax
Request Method:POST
Status Code:200 OK
Request Headers
Accept:*/*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8,bg;q=0.6
Connection:keep-alive
Content-Length:153
Content-Type:application/x-www-form-urlencoded; charset=UTF-8
Cookie:timezoneoffset=-120; viewedJobsGuest=[24]; __atuvc=13%7C11%2C46%7C12; CAKEPHP=dfbf9407743d43eb619a42aa5dbda735; toolbarDisplay=hide
Host:jobsadvent.dev
Origin:URL:localhost
Referer:URL:localhost/search
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.152 Safari/537.36
X-Requested-With:XMLHttpRequest
Form Data
data[title]:the title
data[email]:fake2#hotmail.com
data[alert]:1
Response Headers
Connection:Keep-Alive
Content-Length:57
Content-Type:text/html
Date:Fri, 21 Mar 2014 10:19:06 GMT
Keep-Alive:timeout=5, max=100
Server:Apache/2.2.26 (Unix) DAV/2 PHP/5.4.24 mod_ssl/2.2.26 OpenSSL/0.9.8y
X-Powered-By:PHP/5.4.24
Header on Working computer
Request URL:http://domain.com/alert_subscribers/subscribe_ajax
Request Method:POST
Status Code:200 OK
Request Headers
Accept:*/*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8,bg;q=0.6
Connection:keep-alive
Content-Length:162
Content-Type:application/x-www-form-urlencoded; charset=UTF-8
Cookie:__atuvc=1%7C10%2C5%7C11; timezoneoffset=-120; CAKEPHP=sb3013ffk40h7o1jhsl8ulqfj4; toolbarDisplay=hide
Host:domain.com
Origin:http://domain.com
Referer:http://domain.com/search
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.152 Safari/537.36
X-Requested-With:XMLHttpRequest
Form Data
data[title]:the title
data[email]:fake#hotmail.com
data[alert]:1
Response Headers
Connection:close
Content-Length:57
Content-Type:application/json
Date:Fri, 21 Mar 2014 10:24:32 GMT
Server:Apache/2.2.15 (CentOS)
X-Powered-By:PHP/5.3.3
As for the routes.php file both are identical and contain the following line:
Router::parseExtensions('json');
This could be an issue with your apache settings:
The answer given on Apache sending incorrect response header for .js files suggests that you need something like
<FilesMatch \.php$>
SetHandler application/x-httpd-php
</FilesMatch>
to get the right content types.
Refer to the jQuery.post() documentation. There is a fourth parameter (dataType) that you can use that will force jQuery to coerce the response to the correct datatype. You will need to set that equal to 'json' if you want an object back.
Well, no - computer 1 it is application/json and in the other it is text/html. Both have the same code I posted up there.
There's your problem. jQuery uses the response's Content-Type header as a guide.
The CakePHP docs seem to indicate that $this->RequestHandler->respondAs() may work better if you pass it application/json rather than just json.
JSON parsing should fix it.
$.post(
url, // Various urls of type '/users/add_secondary_email_ajax'
data,
function(res){
var result = JSON.parse(res);
if (typeof(result.success)=='undefined'){
ModalManager.update_body_html(res);
}else{
callback_success(res);
}
}
);
I would set the contentType and dataType in your $.POST request.
$.POST({
contentType : "application/x-www-form-urlencoded; charset=UTF-8",
dataType : "json"
})
when calling api:
$.post();
"dataType" param should be set as "json".if it is not sepecfied, ajax will intelligent guessed (xml, json, script, text, html...).see manual here:
so how could the ajax guess the type of data ?
There is a response header, "Content-Type:", by which the server tell the client what type is data. I think , ajax need this header to guess the data type.
this is your broken computer's response:
Content-Type:text/html
and this is your working computer's response:
Content-Type:application/json
if you don't want to specified the param "dataType" of $.post(), you can change the response header, there must be many ways to change it, like this:
<?php
header("Content-Type:application/json");
?>
That could be messy, but don't get worried until there's something to really worry about.
Statement of fact: one of your servers is behaving as expected and the other is not.
With the way that your error is manifesting, it sounds an awfully lot like you are not specifying your request specifically enough or your borked server is failing Content Negotiation.
There are two basic things that come into play here that you likely already know about: the requester's "Accept" header that allows the user agent to specify the content types that it is willing to receive and the server's ability to interpret that request and serve it appropriately. In absence of an explicitly set Accept header, text\html is the default response type.
Accept Header: RFC2616 Hypertext Transfer Protocol Section 14.1
The Accept request-header field can be used to specify certain media
types which are acceptable for the response. Accept headers can be
used to indicate that the request is specifically limited to a small
set of desired types, as in the case of a request for an in-line
image.
The asterisk "" character is used to group media types into ranges,
with "/" indicating all media types and "type/" indicating all
subtypes of that type. The media-range MAY include media type
parameters that are applicable to that range.
The accept headers that you set for each request indicate that you don't care what the server gives you. You might try setting your accept header to application/json and see if the "broken" server can interpret it and serve you. If that works, then it seems you're just running into an inconsistency with the way the servers are defaulting their response types. This even looks to be what you're asking for it to do. You said you accept all response types. If you don't specify something specific, the most reasonable type for a server to give you is text/html
MIME Types: RFC 2046 Multipurpose Internet Mail Extensions
JSON: RFC 4627 The application/json Media Type for JavaScript Object Notation (JSON)
If setting the Accept header doesn't work for you, you're going to want to check your server's MIME type registration to make sure that [application\json] is registered and configured. That is not an esoteric configuration subject, so it should be available in any server's configuration documentation.
If neither of those approaches work, then the solution is to unplug the offending machine, carry it to the top of the building, and throw it as far as you can.

jQuery JSONP Call towards PHP backend: No HTTP response

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})
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.
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 ?
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/
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 :
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.
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
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 =)
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.

prevent query to captcha generator from YSlow

i have a pretty simple captcha, something like this:
<?php
session_start();
function randomText($length) {
$pattern = "1234567890abcdefghijklmnopqrstuvwxyz";
for($i=0;$i<$length;$i++) {
$key .= $pattern{rand(0,35)};
}
return $key;
}
$textCaptcha=randomText(8);
$_SESSION['tmptxt'] = $textCaptcha;
$captcha = imagecreatefromgif("bgcaptcha.gif");
$colText = imagecolorallocate($captcha, 0, 0, 0);
imagestring($captcha, 5, 16, 7, $textCaptcha, $colText);
header("Content-type: image/gif");
imagegif($captcha);
?>
the problem is that if the user have YSlow installed, the image is query 2 times, so, the captcha is re-generated and never match with the one inserted by the user.
i saw that is only query a second time if i pass the content-type header as gif, if i print it as a normal php, this doesn't happen.
someone have any clue about this? how i can prevent it or identify that the second query is made by YSlow, to do not generate the captcha again.
Regards,
Shadow.
YSlow does request the page components when run, so it sounds like your problem is cases where the user has YSlow installed and it's set to run automatically at each page load.
The best solution may be to adjust your captcha code to not recreate new values within the same session, or if it does to make sure the session variable matches the image sent.
But to your original question about detecting the second query made by YSlow, it's possible if you look at the HTTP headers received.
I just ran a test and found these headers sent with the YSlow request. The User-Agent is set to match the browser (Firefox in my case), but you could check for the presence of X-YQL-Depth as a signal. (YSlow uses YQL for all of its requests.)
Array
(
[Client-IP] => 1.2.3.4
[X-Forwarded-For] => 1.2.3.4, 5.6.7.8
[X-YQL-Depth] => 1
[User-Agent] => Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:8.0.1) Gecko/20100101 Firefox/8.0.1
[Accept-Encoding] => gzip
[Host] => www.example.com
[Connection] => keep-alive
[Via] => HTTP/1.1 htproxy1.ops.sp1.yahoo.net[D1832930] (YahooTrafficServer/1.19.5 [uScM])
)

Place Order fails in Magento OnePage Checkout

I have a Magento store that has been converted to a "one deal at a time" type store, and the checkout process is broken. I've been trying to debug this, but have hit a wall, primarily due to my limited understanding of Magento.
On the saveOrder step, when clicking "Place Order", the page shows "submitting order information, then the message clears and the shopper is still on the Order Review page.
I've analyzed with Firebug and HttpFox, and I can see the order information is being sent
(Request-Line) POST /checkout/onepage/saveOrder/ HTTP/1.1
Host www.domainname.com
User-Agent Mozilla/5.0 (Windows NT 6.0; rv:2.0) Gecko/20100101 Firefox/4.0
Accept text/javascript, text/html, application/xml, text/xml, */*
Accept-Language en-us,en;q=0.5
Accept-Encoding gzip, deflate
Accept-Charset ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive 115
Connection keep-alive
X-Requested-With XMLHttpRequest
X-Prototype-Version 1.6.0.3
Content-Type application/x-www-form-urlencoded; charset=UTF-8
Referer https://www.domainname.com/checkout/onepage/
Content-Length 178
Cookie frontend=cd60252d28cd115d4096cb2bb5b6a043
Pragma no-cache
Cache-Control no-cache
Post Data shows all of the required information:
payment[method] authorizenet
payment[cc_type] VI
payment[cc_number] 4111111111111111
payment[cc_exp_month] 5
payment[cc_exp_year] 2012
payment[cc_cid] 987
My problem seemed similar to this post:
http://fishpig.co.uk/magento-tutorials/magento-checkout-error-undefined-javascript-alert
but I'm not getting an "Undefined" alert, so I added the "else" statement below:
nextStep: function(transport){
if (transport && transport.responseText) {
alert(transport.responseText);
try{
response = eval('(' + transport.responseText + ')');
}
catch (e) {
response = {};
}
if (response.redirect) {
location.href = response.redirect;
return;
}
if (response.success) {
this.isSuccess = true;
window.location=this.successUrl;
}
else{
var msg = response.error_messages;
if (typeof(msg)=='object') {
msg = msg.join("\n");
}
alert(msg);
}
if (response.update_section) {
$('checkout-'+response.update_section.name+'-load').update(response.update_section.html);
response.update_section.html.evalScripts();
}
if (response.goto_section) {
checkout.gotoSection(response.goto_section);
checkout.reloadProgressBlock();
}
} else {
alert('transport.responseText');
}
},
I am getting the JS alert with no text, so it looks like transport.reponseText is empty. The main references to empty response text I've found appear to be related to same-origin policy, which I don't think applies, because my AJAX post is to and from www.domainname.com.
When I call the saveOrder function directly in the browser, I'm receiving a valid response:
https://www.domainname.com/checkout/onepage/saveOrder
{"success":false,"error":true,"error_messages":"Credit card number mismatch with credit card type"}
and HTTPFox shows I'm getting a 200 response from the Ajax call, but the responsetext is simply empty. I find no PHP errors or errors in Magento's exceptions log. The only thing I'm finding that might be related is "Headers already sent' in Magento's system log:
</pre>
2011-09-03T12:14:21+00:00 DEBUG (7): HEADERS ALREADY SENT: <pre>[0] wwwroot/app/code/core/Mage/Core/Controller/Response/Http.php:50
[1] wwwroot/lib/Zend/Controller/Response/Abstract.php:726
[2] wwwroot/app/code/core/Mage/Core/Controller/Response/Http.php:82
[3] wwwroot/app/code/core/Mage/Core/Controller/Varien/Front.php:169
[4] wwwroot/app/Mage.php:459
[5] wwwroot/index.php:67
</pre>
Does anyone have any suggestions why else the responseText is coming back empty?
Custom modules were at fault. Disabling all of the custom modules in the Magento admin does not actually disable them, it only "disables their output".
Setting False in the module configuration resolved the invalid headers error, at which point I was able to debug the custom module issue that was causing the AJAX checkout errors.

Categories