Best ajax questions in June 2012

jQuery: Why does $.ajax() not wait for request to complete before returning?

13 votes

I've just spent 3 hours debugging a bit of code only to find it was caused by me assuming that the execution order of the following code was linear:-

$.ajax( {ajax options} );
console.log('I was assuming this would execute once the ajax request was complete');

This isn't the first time that this has caused me problems and I was just wondering what the reason for this behavior was?

Is it so that any ajax requests don't hold up other script execution that may be unrelated to the ajax request?

Most of the other answers are answering how to deal with this. I'd like to look, very briefly, at why asynchronous is good in this case.

In fact, most in-browser Javascript is asynchronous. Take, for example, this code:

document.getElementById('foo').onclick = function() {
    alert('foo clicked');
};
document.getElementById('bar').onclick = function() {
    alert('bar clicked');
};

Which will run first? You don't know, because of the asynchronicity inherent to the browser model (or in fact most event-driven code). You run code when an event occurs. You set up the document, then wait for the event to happen, and your code could be executed in all kinds of different orders, depending on what events happen first. Javascript code needs to be executed during the whole lifetime of the page, not just when it's first created.

So in general Javascript programming (or at least, Javascript programming beyond the simplest level) is often going to be asynchronous. Furthermore, it makes a great deal of sense for HTTP requests to be asynchronous as well.

First, as you imply in your question, making the code synchronous would block execution. That is to say, you probably don't want to make an animation wait two seconds to start because you're making an HTTP request two lines further up. Server response times can be (a) irregular and (b) slow, so it makes no sense for the design of your application to depend on the speed of your server's response.

Second, and more importantly, your user isn't going to stop using the page because your script is making an AJAX call. Your user doesn't care. Your user probably will care that your normal onscroll behaviour isn't working because your script is currently tied up with an unrelated AJAX request. To tie in with the asynchronous nature of the whole of browser Javascript programming, the vast majority of HTTP calls should be non-blocking, asynchronous.

Are there substantial differences in the way browsers implement the same-origin policy?

10 votes

I have a form on my homepage that is set up to submit via XHR POST to the URL https://mydomain.com/send_sms.

When I visit the non-SSL version of the homepage in Internet Explorer (http://mydomain.com) & submit the form, nothing happens. In Webkit console, I receive a helpful error stating Origin http://mydomain.com is not allowed by Access-Control-Allow-Origin.

In Firefox 13 however, the request clearly submits & a returns a 200 OK, though the response body is blank. Furthermore, the server-side action (sending an SMS) is in fact triggered by the Firefox request but not the other browsers.

I always thought the same-origin policy denied even the sending of the request, but perhaps it's the browser receiving data from the response that's disallowed?

Anyone know if this is a purposeful difference in implementation (or possibly even an oversight) by Mozilla?

First of all, http://example.com and https://example.com are different origins. For XHR Level 1 this would mean, cross-origin requests are not allowed.

But for the current XHR (Level 2), which supports cross-origin requests when CORS is supported (by both server and client!), a cross-origin request can either be

For simple cross-origin requests, the browser is allowed to send the request. But when the response is received, it needs to check whether the server allows to share the resource. This is where the Access-Control-Allow-Origin header field and other Access-Control-* response header fields are checked. And only if this check is passed, the browser allows the script to read the response.

For other cross-origin requests, a preflight is required to negotiate with the server what information is allowed to be sent in the actual request. This preflight request is basically a OPTIONS request telling the server what the actual request will contain (request method and header fields). Then the server can decide whether it allows such request or not.

In your case, the observed behavior can have multiple reasons. I guess your send_sms script just doesn’t support the server side part for CORS.

jquery getting values inside a ul li tag, but don't want a certain tag

6 votes

I'm trying to get text value inside an li tag, but it has another tag that I don't want

example:

<ul>
<li><a class="close">x</a>text</li>
<li><a class="close">x</a>more text</li>
<li><a class="close">x</a>wohoooo more text</li>
</ul>

I can get tag like so

$("ul li").text();

but it also captures x from a. How do I remove the a tag? There's gotta be a simple solution that I'm not familiar with,

Thanks!

$("ul li").contents(':not(.close)').text()

children() does not return text nodes; to get all children including text and comment nodes, use .contents() http://api.jquery.com/children/

Number of Ajax Requests increases with live jQuery

6 votes

I have the code below which I use clone() and live(). The code is being load in a jQuery UI dialog with a link. Whenever I click the link it goes to server and fill the dialog with the code below. The first time page is being loaded it works fine, but if I close the dialog and click the link again to get the dialog the number of Ajax requests which is being send increases.

The first time I send trigger the change I send only one request, I close the dialog and load it again and then trigger the change, it send two Ajax request at same time, the third time three request at same time and so on.

Where do you think my problem is?

<input id="TaskId" name="TaskId" type="hidden" value="18" />
<div id="MainDiv">
    <div id="toClone">
        <div style="display: inline;">
            <select id="Tasksess">
                <option value="">لطفاً کار را انتخاب کنيد</option>
                <optgroup label="کار های جديد">
                        <option value="16"style="">q3fe</option>
                        <option value="18"style="">fjhv j</option>
                        <option value="19"style="">wref</option>
                        <option value="25"style="">ff</option>
                </optgroup>
                <optgroup label="کار های در دست اقدام">
                        <option value="13"style="">rr</option>
                        <option value="15"style="">yy</option>
                </optgroup>
                <optgroup label="کار های تمام شده">
                        <option value="14"style="">tt</option>
                        <option value="18"style="">fjhv j</option>
                </optgroup>
            </select>
        </div>
        <div style="display: inline;">
            <select id="Statusess" name="Statusess"><option value="">لطفاً وابستگی را انتخاب کنيد</option>
<option value="1">پيشنياز</option>
<option value="2">همنياز</option>
</select>
        </div>
        <div style="display: none;" id="Ok">
            ok
        </div>
        <div style="display: none;" id="noOk">
            تکراری
        </div>
        <div id="loadingGif" style="display: none;">
            <img src="/Content/Images/ajax-loader/253L.gif" alt=""/>
        </div>
    </div>
</div>
<script type="text/javascript">
    $(document).ready(function () {

        var Maindiv = $("#MainDiv");
        var toClone = $("#toClone");

        //$("#Statusess").each(function () {
            $("#Statusess").live('change', function () {
                if ($(this).find(":selected").val() != "") {                    
                    if ($(this).parent().prev().find(":selected").val() != "") {
                        $(this).parent().parent().find("#loadingGif").attr("style", "display: inline;");
                        $.ajax({
                            url: '/ProjectAdmin/Project/AddTaskDependency?MainTaskId=' + $("#TaskId").val() + '&DependentTaskId=' + $(this).parent().prev().find(":selected").val() + '&Status=' + $(this).find(":selected").val(),
                            type: 'GET',
                            success: function (data, status) {
                                if (data != "0") {
                                    $(this).parent().parent().find("#Ok").attr("style", "display: inline;");
                                    $(this).parent().parent().find("#noOk").attr("style", "display: none;");
                                }
                                else if (data == "0") {
                                    $(this).parent().parent().find("#Ok").attr("style", "display: none;");
                                    $(this).parent().parent().find("#noOk").attr("style", "display: inline;");
                                }
                                var div = $('div:eq(0)', Maindiv).clone();
                                Maindiv.append(div);
                            }
                        });
                        $(this).parent().parent().find("#loadingGif").attr("style", "display: none;");

                    }
                }
            });
        //});

    });
</script>

as stated above you should use .delegate() instead of .live().

In order to use delegate all you need to do is specify a parent in which you will be listening to and a selector on which it's going to act.

Try this:

<script>
$(function(){
var Maindiv = $("#MainDiv");
var toClone = $("#toClone");

$("#MainDiv").delegate('#Statusess','change', function () {
    if ($(this).find(":selected").val() != "") {                    
      if ($(this).parent().prev().find(":selected").val() != "") {
        $(this).parent().parent().find("#loadingGif").attr("style", "display: inline;");
        $.ajax({
            url: '/echo/html/',
            type: 'POST',
            success: function (data, status) {
                data = "1";
                if (data != "0") {
                    $(this).parent().parent().find("#Ok").attr("style", "display: inline;");
                    $(this).parent().parent().find("#noOk").attr("style", "display: none;");
                }
                else if (data == "0") {
                    $(this).parent().parent().find("#Ok").attr("style", "display: none;");
                    $(this).parent().parent().find("#noOk").attr("style", "display: inline;");
                }
                var div = $('div:eq(0)', Maindiv).clone();
                Maindiv.append(div);
            }
        });
        $(this).parent().parent().find("#loadingGif").attr("style", "display: none;");

    }
  }
});
});
</script>

Here you a have a working jsfiddle, also here is a link for reference to .delegate() function.

MVC3 Ajax.BeginForm OnSuccess Doesn't Run in Firefox

6 votes

FINAL EDIT:

After following the answer from Darin Dimitrov, I have found that the problem ended up being that the AJAX call to the Controller's method UpdateForm() was returning an empty string. This was a modification that I found necessary some time ago after experiencing a different problem. Passing an empty string was causing Firefox's parser to choke (while Chrome and IE didn't care, apparently) so I replaced the empty string with an empty div.

Edit:

Thanks to Darin Dimitrov's suggestions below, I have found that the reason I was having trouble is due to an error being thrown whenever the form in question is being submitted.

JQuery Error

The error reads "Node cannot be inserted at the specified point in the heirarchy". This is thrown each and every time the form is submitted. I noticed in the POST data that it seems to think this is an XMLHttpRequest. Is that the cause (the AJAX request in question is just returning HTML)? Here is the POST data from Firebug:

POST Data 1

POST Data 2

POST Data 3

This error reads "XML Parsing Error -- No Element Found".

FYI - the HTML being returned is always an empty string...


I have an MVC3 application running on IIS7. In one of my views, I have a form being built using a Microsoft HTML helper function:

@using (Ajax.BeginForm("UpdateForm", new AjaxOptions { UpdateTargetId = "TargetDiv", InsertionMode = InsertionMode.InsertAfter, OnSuccess = "ClearTextBox" }))
{
    @Html.TextArea("txtInput", new { id = "txtInput", cols = "20", rows = "5", wrap = "virtual" })
    <input id="send" class="button" type="submit" value="Send"/><br />
} 

This generates the following HTML when the Controller provides this view:

<form action="/RootName/ControllerName/UpdateForm" data-ajax="true" data-ajax-mode="after" data-ajax-success="ClearTextBox" data-ajax-update="#TargetDiv" id="form0" method="post">
     <textarea cols="20" id="txtInput" name="txtInput" rows="5" wrap="virtual"></textarea>    
     <input id="send" class="button" type="submit" value="Send"><br>
</form>

What I'm basically trying to do here is take the text inside the TextArea called txtInput and append it to the end of the Div called TargetDiv whenever the Send button above is clicked and clear out the text from txtInput after the appending is complete by means of the ClearTextBox() method (Javascript). The append always works in every browser; and when I run in Internet Explorer or Chrome, the clearing of the text works just fine. However, Firefox doesn't seem to want to call the ClearTextBox() method.

Is Firefox not compatible with this data-ajax-success option in the form signature?


Things I've Tried

I found this guy: Ajax.BeginForm doesn't call onSuccess

The solution is to add this script:

<script src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")" type="text/javascript"></script>

I am calling this script:

<script src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script>

...but I tried swapping it out just in case. No joy.

I was asked to try changing the method call to include parentheses by some folks in the C# chat room so that the HTML came out like this:

<form action="/WebChat/TMWC/UpdateForm" data-ajax="true" data-ajax-mode="after" data-ajax-success="ClearTextBox()" data-ajax-update="#chatText" id="form0" method="post">
     <textarea cols="20" id="txtInput" name="txtInput" rows="5" wrap="virtual"></textarea>    
     <input id="send" class="button" type="submit" value="Send"><br>
</form>

But that didn't help.

The folks in C# Chat also suggested I replace the Javascript call with an alert - something like this:

<form action="/WebChat/TMWC/UpdateForm" data-ajax="true" data-ajax-mode="after" data-ajax-success="alert('yo!')" data-ajax-update="#chatText" id="form0" method="post">
     <textarea cols="20" id="txtInput" name="txtInput" rows="5" wrap="virtual"></textarea>    
     <input id="send" class="button" type="submit" value="Send"><br>
</form>

While Chrome pops the message box, Firefox does not!

Status no repro in a newly created ASP.NET MVC 3 application.

Controller:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View();
    }

    [HttpPost]
    public ActionResult UpdateForm()
    {
        return Content(DateTime.Now.ToLongTimeString());
    }
}

View (~/Views/Home/Index.cshtml):

<script src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")" type="text/javascript"></script>
<script type="text/javascript">
    function ClearTextBox() {
        $('textarea').val(''); 
    }
</script>

<form action="/Home/UpdateForm" data-ajax="true" data-ajax-mode="after" data-ajax-success="ClearTextBox" data-ajax-update="#TargetDiv" id="form0" method="post">
     <textarea cols="20" id="txtInput" name="txtInput" rows="5" wrap="virtual"></textarea>    
     <input id="send" class="button" type="submit" value="Send"><br>
</form>

<div id="TargetDiv"></div>

Works perfectly fine in Chrome, FF and IE.

Also you might want to ensure that the Content-Type response HTTP header matches the actual response that you are sending. For example I have seen so many people send the application/json response header with some invalid JSON in the response body which produces the more sensitive parsers to choke.

JavaScript/jQuery clearInterval being set in .each

5 votes

So I have an interval I create for each of my posts, the issue is that I load new posts and remove the old ones, so obviously I'd like to stop the interval for the previous posts. However I can't seem to figure out how to do this. Could someone explain to me how to properly go about doing this? I'm completely lost.

$(".post").each(function(){
    myInterval = setInterval("postStats('"+$(this).attr('id')+"')", 500);
});

function postStats(pid) {
    //do some stuff
}

$(".button").click(function(){
    clearInterval(myInterval);
});

You can store the interval ID in a data attribute:

$(".post").each(function () {
    var that = this;
    var myInterval = setInterval(function () {
        postStats(that.id);
    }, 500);
    $(this).data("i", myInterval);
});

and clear the interval specific to each .post like so:

$(".button").click(function () {

    // assuming the button is inside a post
    clearInterval($(this).closest(".post").data("i"));
});

and like SiGanteng said, you should pass a function object to setInterval rather than a string, which only gets eval'd.

PHP/Ajax/jQuery - Passing a jquery value to a php script

5 votes

I have a bookings.php page which has a jqgrid that displays all the bookings that have been made online. When you double click a row, this opens a jq dialog that displays all the details about there booking. Also, when you double click, I have a variable defined which is the booking reference which I want to pass to a php script:

var brData = rowData['bookref'];

I am sending this variable via ajax:

function getGridRow(brData) {

   $.ajax({

    // Request sent from control panel, so send to cp.request.php (which is the handler)
    url: 'scripts/php/bootstrp/all.request.php',
    type: 'GET',

    // Build data array - look at the '$_REQUEST' parameters in the 'insert' function
    data: {


        //ft: "getDGRow",
        rowdata: 'fnme=getDGRow&row_data='+brData,
        data: brData,

        // Either pass a row id as the 'id' OR a where clause as the 'condition' never both
        id: null,
        condition: null
    },
    dataType: 'text',
    timeout: 20000,
    error: function(){
        alert("It failed");
        $('#cp-div-error').html('');
        $('#cp-div-error').append('<p>There was an error inserting the data, please try again later.</p>');
        $('#cp-div-error').dialog('open');
    },
    success: function(response){

        // Refresh page

       // response = brData;
       // alert(response);

    }
});


}

Here is the switch case for all.inc.php:

case 'getDGRow':
//header('Content-type: text/xml');
DatagridController::getGridRow($_REQUEST['rowdata']);
break;

This is the PHP function that I am sending the jquery variable to, to use within my PHP code:

public static function getGridRow($rowdata) {

    $rowdata = $_GET['data'];
    echo $rowdata;

    $pdo = new SQL();
    $dbh = $pdo->connect(Database::$serverIP, Database::$serverPort, Database::$dbName, Database::$user, Database::$pass);

    try {

        $query = ("SELECT * FROM tblbookings WHERE bookref = '$rowdata'");

        $stmt = $dbh->prepare($query);

        $stmt->execute();

        $row = $stmt->fetch(PDO::FETCH_BOTH);

        BookingDocket::set_id($row['id']);
        BookingDocket::set_bookref($row['bookref']);
        BookingDocket::set_bookdate($row['bookingdate']);
        BookingDocket::set_returndate($row['returndate']);
        BookingDocket::set_journeytype($row['journeytype']);
        BookingDocket::set_passtel($row['passengertel']);
        BookingDocket::set_returndate($row['returndate']);



        $stmt->closeCursor();

    }

    catch (PDOException $pe) {
        die("Error: " .$pe->getMessage(). " Query: ".$stmt->queryString);
    }

    $dbh = null;

}


}

I have put echo $rowdata; in the PHP function to see if the variable is being passed which it is as I can see 'BR12345' in the firebug console. The problem is that this query:

 $query = ("SELECT * FROM tblbookings WHERE bookref = '$rowdata'");

is not fetching any results. If I was to put:

 $query = ("SELECT * FROM tblbookings WHERE bookref = 'BR12345'");

it does fetch the results that I need so I can't understand why this query isn't working when the variable brData is being passed to $rowdata

Any suggestions?

Wondering why you have a prepared statement in your code but not actually using it properly.

$stmt = $dbh->prepare("SELECT * FROM tblbookings WHERE bookref = :data");
$stmt->execute(array(
    ':date' => trim($rowdata),
));

I've added trim() to make sure there are no spaces or newlines around it that could mess things up.

Update

It's debug time:

public static function getGridRow($rowdata) {

    $rowdata = $_GET['data'];
    echo $rowdata;

Add the following lines:

    echo "=====DEBUG====== ";
    var_dump($rowdata); 
    echo " =====DEBUG====== ";
    exit;

This will write the value and immediately stop your script so you can inspect its value in detail.

How do i get image using jquery ajax?

5 votes

I am using jcrop to crop the image in my php application.I am using below code to pass the coordinate values and image path using ajax,

function checkCoords(index)
    {
            if (parseInt(jQuery('#w').val())){
                    jQuery.ajax({
                        type    : "POST",
                        cache: false,
                        dataType: 'html',
                        data    : {
                                x : jQuery('#x').val(),
                                y : jQuery('#y').val(),
                                w : jQuery('#w').val(),
                                h : jQuery('#h').val(),
                       image_path : jQuery('#jc-hidden-image'+index).attr('src')
                        },
                        url     : BASE_URL+'apps/configure/cropimage',
                        success : function(response) { 
                                jQuery(".preview_crop").html(response);
                        }
                    });                     
            } 
            else{
                alert('Please select a crop region then press Crop button.');
            }

In Controller, I use the ajax value as below,

  public function cropimageAction(){
        $params = $this->getRequest()->getParams();
        //d($params);
        if ($_SERVER['REQUEST_METHOD'] == 'POST')
        {
                $targ_w = $targ_h = 150;
                $jpeg_quality = 90;

                $src = $params['image_path'];
                $img_r = imagecreatefromjpeg($src);
                $dst_r = ImageCreateTrueColor( $targ_w, $targ_h );

                $image  = imagecopyresampled($dst_r,$img_r,0,0,$_POST['x'],$_POST['y'],$targ_w,$targ_h,$_POST['w'],$_POST['h']);

               header('Content-type: image/jpeg');
                imagejpeg($dst_r,null,$jpeg_quality);

                exit;
        }        
    }

I got the response as something like

��(��(��(��(��

Instead of cropped image, got some symbol. Need to get cropped image in ajax response. What i done wrong on this ?

You are sending the full image data back as response, instead save the image on the server and send the URL to it as a response

instead

header('Content-type: image/jpeg');
imagejpeg($dst_r,null,$jpeg_quality);

have this

imagejpeg($dst_r,"path/where/to/save/image.jpg",$jpeg_quality);
echo "path/where/to/save/image.jpg";

Also, your success function should look like

success : function(url) { 
    jQuery(".preview_crop").html('<img src="' + url + '" />');
}

ajax success function is printing [object Object] instead of plain text. Why?

5 votes
function ajaxsubmit(){
$.ajax({
    url: "/update",
    type: "POST",
    dataType: "html"
}).success(function(data) {
      $('#result').html(data);
  });
}

and my java function:

public static Result ajaxupdate(){

    String done = "very good";
    return ok("very good").as("text/plain");
}

the alert is giving [object Object], instead of plain text "very good". why?

add dataType: "text" and change complete() with success()

function ajaxsubmit(){
    $.ajax({
        url: "/update",
        type: "POST",
        dataType: "html"
    }).success(function(data) {
          $('#result').html(data);
      });
    }

Getting html() of a div of another page with AJAX

4 votes

First of all, please note that I'm a beginner at javascript/jQuery coding. Basically I need a javascript/jQuery code to get .html() of a div which is located on another page and display it on a current page, where that div doesn't exist. Is it possisle? If yes, how to do it? (I'm assuming that I need to use AJAX).

Thanks in advance.

Make a ajax call to a php or any other file , use CURL or other tools to grab the page you want and extract the div and echo it and then when you get back the html just put it inside a div in your page

    $.ajax({
    url: 'somefile.html',
    success: function(data) {
                    data=$(data).find('div#id');
        $('#mydiv').html(data);
        alert('Done.');
     }
    });

How is it possible, that ajaxing is much more slower in Chrome and IE than Mozilla?

4 votes

I would like to ask you to find the point, why the site -I'm working on- is slow.

the conditions of the problem:

  • large row count (so I think maybe the problem is related to this.)
  • there is ajaxing event (I have tired to comment it out and the problem disappeared)
  • using not Mozilla (this freeze effect appear in IE and Chrome)

description of the problem (see the image):

  • I change the value of input
  • after there is an ajax call (in order to calculate prize) and it takes in FF about 30 ms otherwise more than 1 s
  • there is a freeze until the ajax finished (but ajax is not set to async:false)
  • only after that can I change the next input

I have tired to reproduce the error, but I could't. So see the original site:

site: http://fejl.teleprint.hu/foto/fotokidolgozas/elohivas-beallitasok.php

Log in and pass: d838292@rtrtr.com

enter image description here

Thank you for any help!

Code:

$('#cikkek,#magic_bar').on("change","select,textarea,input[type!=hidden]",function(event_object){
    if( $(this).attr('name') == "kijelolve" && !$(this).parents('#magic_bar').length)return true;

    var cikk_id = $(this).parents('.cikk').attr('id');
    var cikk_tipus = $("input[name=cikk_tipus]").val();
    var tulajdonsag = $(this).attr('name');     
    var ertek = $(this).val();
    if(ertek == "-1")return false;      
    if($(this).is('[type=checkbox]'))ertek = $(this).prop("checked")?'1':'0';

    if(cikk_tipus=='fotokidolgozas' && (tulajdonsag=='meret'||tulajdonsag=='vagas'))
        {
            var sor = $(event_object.target).parents('.cikk');
            var act_meret = sor.find('select[name=meret]').val();
            var act_fill = sor.find('select[name=vagas]').val();
            var act_zold_class = sor.find("input[name=zold_"+act_meret+"]").val()=="1" ?"zold":"feher" ;
            var name = "src_"+act_meret+"_"+act_fill;                   
            var name2 = "szoveges_uzenet_"+act_meret+"_"+act_fill;                  
            sor.find(".img_cont").find("img").attr("src",sor.find("input[name="+name+"]").val());   
            sor.find(".szoveges_uzenet").text(sor.find("input[name="+name2+"]").val());
            sor.find(".dpi_megfelel").text(sor.find("input[name=minoseg_"+act_meret+"]").val()+" ("+sor.find("input[name=dpi_"+act_meret+"]").val()+" dpi)");
            sor.find("select[name=meret]").removeClass("feher zold").addClass(act_zold_class);
        }

    var before = now();

    //this is the ajax part
    if(ajax_modositaskor)
    $.post('/_fn/cikk/mod.php',{
        'cikk_tipus':cikk_tipus,
        'cikk_id':cikk_id,
        'tulajdonsag':tulajdonsag,
        'ertek':ertek
        },function(a){
            var elapsed = now() - before;
            if(a[0]!="1")
            {
                //error
                alert(a[0]);
                return;
            }
            if(a[1]!="-1")
            {
                //there is new price
                $(event_object.target).parents('.cikk').find('.ar').text(a[1]);     
            }
            if(a[2]!="-1")$('#cikkek_ara').text(a[2]);
            osszegzest_frissit(a[3]);               
            var php_time = Math.round(a[4])
            a_min = Math.min(a_min,elapsed);
            p_min = Math.min(p_min,parseFloat(php_time));
            a_max = Math.max(a_max,elapsed);
            p_max = Math.max(p_max,parseFloat(php_time));
            if(!a_avg)a_avg = elapsed;else a_avg= Math.round((a_avg+elapsed)/2);
            if(!p_avg)p_avg = php_time;else p_avg = Math.round((p_avg+php_time)/2);             
            trace("ajax="+elapsed+"\tphp="+php_time+"\tajax_min="+a_min+"\tphp_min="+p_min+"\tajax_max="+a_max+" \tphp_max="+p_max+"\tajax_avg="+a_avg+" \tphp_avg="+p_avg);                

        },"json").error(function() { postHiba() });


});

The problem was that the hidden data was too large (see my other question), and it decreased the processing time. (Firefox seems to be well coded, because this does not mattered)

Now the problem is fixed.

What responses does jQuery.ajax consider to be "success"?

4 votes

I have a jQuery AJAX post request that is unexpectedly triggering the error callback instead of success. One random suspicion I have is the 302 status code it is receiving, although that may be wrong.

I looked at the documentation, but I feel like one thing is a bit unclear: What is jQuery's definition of a successful request?

If the response is between 199 and 300 ( >= 200 and < 300 ) or equal to 304 and the responseText can be successfully converted to the dataType that you provide (text by default), it is considered a successful request.

For example, if you return JSON and you get a 200 response status but it fails, it is more than likely a JSON parser problem meaning your JSON is not valid.

If you are returning HTML or XML and it fails with a 200 response status, the responsetext couldn't be converted to HTML or XML respectively (commonly happens in IE with invalid html/xml)

Callback function for jQuery .html()?

4 votes

I have the following code:

$.ajax({
      type: 'GET',
      url: 'index.php?route=checkout/onepagecheckout/getpaypaldata',
      dataType: 'json',
      success: function(json) {
                              $('#pp_info').html(json['output']);
                              $('#payment').submit();
                              }
      });

The ajax requests receives a json object containing a html form like :

<form id="payment" method="post" action="https://www.paypal.com/cgi-bin/webscr">
<input type="hidden" value="_cart" name="cmd">
<input type="hidden" value="1" name="upload">
<input type="hidden" value="test@yahoo.ca" name="business">
<input type="hidden" value="Sample Item Name" name="item_name_1">
<input type="hidden" value="TESTI-1" name="item_number_1">
<input type="hidden" value="104.98" name="amount_1">
<input type="hidden" value="1" name="quantity_1">
<input type="hidden" value="0" name="weight_1">
<input type="hidden" value="Type" name="on0_1">
<input type="hidden" value="As Shown" name="os0_1">
<input type="hidden" value="Delivery Date" name="on1_1">
<input type="hidden" value="Jun 23,2012" name="os1_1">
<input type="hidden" value="Comments" name="on3_1">
<input type="hidden" value="test message" name="os3_1">
</form>

which contains the information that PayPal requires in order to process the order. Everything works fine except I believe sometimes the form gets submitted before the jQuery .html function is done with loading the html content.

Is there any callback function for .html ? or any other method that I can use to solve the issue ? the PayPal data comes as a HTML form and I can't change that part, so I only have one option which is somehow load the html content and submit the form !

You may try this

success: function(json) {
    $('#pp_info').html(json['output']).promise().done(function(){
        $('#payment').submit();
    });
}