javascript - примеры - js ajax post




Как я могу получить jQuery для выполнения синхронного, а не асинхронного запроса Ajax? (9)

Все эти ответы не учитывают, что выполнение Ajax-вызова с помощью async: false приведет к зависанию браузера, пока не будет завершен запрос Ajax. Использование библиотеки управления потоками позволит решить эту проблему, не повесив браузер. Вот пример с Frame.js :

beforecreate: function(node,targetNode,type,to) {

    Frame(function(next)){

        jQuery.get('http://example.com/catalog/create/', next);
    });

    Frame(function(next, response)){

        alert(response);
        next();
    });

    Frame.init();
}

У меня есть виджет JavaScript, который предоставляет стандартные точки расширения. Одна из них - это функция beforecreate . Он должен возвращать false чтобы предотвратить создание элемента.

Я добавил вызов Ajax в эту функцию, используя jQuery:

beforecreate: function (node, targetNode, type, to) {
  jQuery.get('http://example.com/catalog/create/' + targetNode.id + '?name=' + encode(to.inp[0].value),

  function (result) {
    if (result.isOk == false) 
        alert(result.message);
  });
}

Но я хочу, чтобы мой виджет не создавал этот элемент, поэтому я должен возвращать false в функции mother, а не в обратном вызове. Есть ли способ выполнить синхронный запрос AJAX с использованием jQuery или любого другого API-интерфейса в браузере?


Вы можете установить jQuery Ajax в синхронном режиме, вызвав

jQuery.ajaxSetup({async:false});

Затем выполните ваши вызовы Ajax с помощью jQuery.get( ... );

Затем просто включайте его снова

jQuery.ajaxSetup({async:true});

Я предполагаю, что это работает так же, как предложено @Adam, но может быть полезно кому-то, кто хочет перенастроить свои jQuery.get() или jQuery.post() в более сложный синтаксис jQuery.ajax() .


Имейте в виду, что если вы выполняете междоменный вызов Ajax (используя JSONP ), вы не можете делать это синхронно, async флаг будет игнорироваться jQuery.

$.ajax({
    url: "testserver.php",
    dataType: 'jsonp', // jsonp
    async: false //IGNORED!!
});

Для JSONP-звонков вы можете использовать:

  1. Ajax-вызов в ваш собственный домен - и выполнить междоменный вызов на стороне сервера
  2. Измените свой код для работы асинхронно
  3. Используйте библиотеку «функционального секвенсора», такую ​​как Frame.js (этот answer )
  4. Блокируйте пользовательский интерфейс вместо того, чтобы блокировать выполнение (этот answer ) (мой любимый способ)

Отличное решение! Я заметил, что когда я попытался реализовать его, если бы я вернул значение в предложение success, оно вернулось как неопределенное. Мне пришлось хранить его в переменной и возвращать эту переменную. Это метод, который я придумал:

function getWhatever() {
  // strUrl is whatever URL you need to call
  var strUrl = "", strReturn = "";

  jQuery.ajax({
    url: strUrl,
    success: function(html) {
      strReturn = html;
    },
    async:false
  });

  return strReturn;
}

Примечание. Вы не должны использовать async из-за этого:

Начиная с Gecko 30.0 (Firefox 30.0 / Thunderbird 30.0 / SeaMonkey 2.27), синхронные запросы в основном потоке устарели из-за негативных последствий для пользователя.

Chrome даже предупреждает об этом в консоли:

Синхронный XMLHttpRequest в основном потоке устарел из-за его пагубных последствий для опыта конечного пользователя. Для получения дополнительной справки проверьте https://xhr.spec.whatwg.org/ .

Это может сломать вашу страницу, если вы делаете что-то подобное, так как она может перестать работать в любой день.

Если вы хотите сделать это так, как будто это синхронно, но все равно не блокировать, вы должны использовать async / await и, возможно, также некоторый ajax, основанный на обещаниях, таких как новый API Fetch

async function foo() {
  var res = await fetch(url)
  console.log(res.ok)
  var json = await res.json()
  console.log(json)
}

С async: false вы получаете заблокированный браузер. Для неблокирующего синхронного решения вы можете использовать следующее:

ES6 / ECMAScript2015

С ES6 вы можете использовать генератор и библиотеку co :

beforecreate: function (node, targetNode, type, to) {
    co(function*(){  
        let result = yield jQuery.get('http://example.com/catalog/create/' + targetNode.id + '?name=' + encode(to.inp[0].value));
        //Just use the result here
    });
}

ES7

С ES7 вы можете просто использовать asyc wait:

beforecreate: function (node, targetNode, type, to) {
    (async function(){
        let result = await jQuery.get('http://example.com/catalog/create/' + targetNode.id + '?name=' + encode(to.inp[0].value));
        //Just use the result here
    })(); 
}

Я использовал ответ, данный Carcione, и изменил его, чтобы использовать JSON.

 function getUrlJsonSync(url){

    var jqxhr = $.ajax({
        type: "GET",
        url: url,
        dataType: 'json',
        cache: false,
        async: false
    });

    // 'async' has to be 'false' for this to work
    var response = {valid: jqxhr.statusText,  data: jqxhr.responseJSON};

    return response;
}    

function testGetUrlJsonSync()
{
    var reply = getUrlJsonSync("myurl");

    if (reply.valid == 'OK')
    {
        console.dir(reply.data);
    }
    else
    {
        alert('not valid');
    }    
}

Я добавил dataType 'JSON' и изменил .responseText на responseJSON .

Я также получил статус с использованием свойства statusText возвращаемого объекта. Обратите внимание, что это статус ответа Ajax, а не действителен ли JSON.

Внутренний сервер должен вернуть ответ в правильном (правильно сформированном) JSON, иначе возвращаемый объект будет неопределенным.

При ответе на исходный вопрос необходимо учитывать два аспекта. Один говорит Ajax выполнять синхронно (путем установки async: false ), а другой возвращает ответ через оператор возврата вызывающей функции, а не в функцию обратного вызова.

Я также пробовал его с помощью POST, и он работал.

Я изменил GET на POST и добавил данные: postdata

function postUrlJsonSync(url, postdata){

    var jqxhr = $.ajax({
        type: "POST",
        url: url,
        data: postdata,
        dataType: 'json',
        cache: false,
        async: false
    });

    // 'async' has to be 'false' for this to work
    var response = {valid: jqxhr.statusText,  data: jqxhr.responseJSON};

    return response;
}

Обратите внимание, что приведенный выше код работает только в случае, когда async является ложным . Если вы должны были установить async: true, возвращаемый объект jqxhr недействителен во время вызова AJAX, только позже, когда асинхронный вызов будет завершен, но слишком поздно установить переменную ответа .


это моя простая реализация для запросов ASYNC с помощью jQuery. Надеюсь, это поможет кому угодно.

var queueUrlsForRemove = [
    'http://dev-myurl.com/image/1', 
    'http://dev-myurl.com/image/2',
    'http://dev-myurl.com/image/3',
];

var queueImagesDelete = function(){

    deleteImage( queueUrlsForRemove.splice(0,1), function(){
        if (queueUrlsForRemove.length > 0) {
            queueImagesDelete();
        }
    });

}

var deleteImage = function(url, callback) {
    $.ajax({
        url: url,
        method: 'DELETE'
    }).done(function(response){
        typeof(callback) == 'function' ? callback(response) : null;
    });
}

queueImagesDelete();

function getURL(url){
    return $.ajax({
        type: "GET",
        url: url,
        cache: false,
        async: false
    }).responseText;
}


//example use
var msg=getURL("message.php");
alert(msg);




asynchronous