Непонятное поведение jQuery $ .ajax (), когда данные содержат последовательные знаки вопроса - PullRequest
25 голосов
/ 18 апреля 2011

Надеюсь, это достаточно ясно, я потратил много энергии, пытаясь решить эту проблему, поэтому у меня может не хватить времени на написание идеального вопроса. Кроме того, это, возможно, придется включить в отчет об ошибках jQuery, но я бы лучше сначала опубликовал его здесь, поскольку я новичок в JavaScript, так что, возможно, я сделал что-то не так ...

Я создал следующий фрагмент кода, чтобы воспроизвести его. Он использует PHP для вывода полученных данных в браузер, хотя может работать без PHP.

Проблема может быть воспроизведена в Firefox 4 и Chrome 10. Вам понадобится консоль, чтобы увидеть, что происходит.

Вот код:

<code><?
$input = file_get_contents('php://input');
if (isset($input) and !empty($input)) {
    echo $input;
    die();
}

?>

<html>
    <head>
        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js"></script>
        <script>
            $(function(){
                var jsonData = {
                    "something":"??"
                };
                jsonData = JSON.stringify(jsonData);
                var onSuccess = function(data){
                    console.log("Ajax Success!");
                    console.log(data);
                }
                var onError = function(jqXHR, textStatus, errorThrown){
                    console.log("Ajax Error: "+textStatus);
                    console.log("More info:");
                    console.log(errorThrown);           
                    console.log(jqXHR);         
                }
                console.log("Now sending this: "+jsonData+" through Ajax...");
                var ajaxCmd = {
                    "url"       : "test.php", 
                    "dataType": "json",
                    "type"  : "POST",
                    "async" : false,
                    "error"     : onError,
                    "success"   : onSuccess,
                    "data"  : jsonData
                };
                $.ajax(ajaxCmd);
            });
        </script>
    </head>
    <body>
        <pre>Check your JavaScript console...

При загрузке выдает некоторую явно не связанную ошибку или исключение при разборе (в зависимости от браузера). JSON, который должен быть отправлен, это {"что-то": "??"}, но если вы проверите его на вкладке сети Firebug (или аналога Chrome), вы увидите, что "??" заменяется некоторой строкой jQuery, которая выглядит следующим образом: jQuery152026845051744021475_1303152126170

И это то, что получает сервер.

Эта проблема возникает, только если в поле значения внутри отправленного объекта JSON есть два или более последовательных вопросительных знака, даже если там есть другие буквы. С одним знаком вопроса это похоже на работу. Также изменение «dataType» на «text» исправляет это. Но мне нужны все эти функции!

Если вы закомментируете "jsonData = JSON.stringify (jsonData);" или "$ .ajax (ajaxCmd)"; ошибки также чудесным образом исчезают.

Дополнительная информация:

Выход консоли Chrome:

test.php:21Now sending this: {"something":"??"} through Ajax...
jquery.min.js:16Uncaught SyntaxError: Unexpected token :
test.php:16Ajax Error: parsererror
test.php:17More info:
test.php:18jQuery15206220591682940722_1303153398797 was not called
test.php:19
Object

Firefox Firebug вывод:

Now sending this: {"something":"??"} through Ajax...
Ajax Error: parsererror
More info:
jQuery15206494160738701454_1303153492631 was not called
Object { readyState=4, responseText="{"something":"jQuery152...8701454_1303153492631"}", more...}
invalid label
{"something":"jQuery15206494160738701454_1303153492631"}

Ответы [ 9 ]

19 голосов
/ 15 июля 2013

jQuery использует ?? в качестве заполнителя для функции обратного вызова при использовании jsonp.Когда он анализирует запрос Ajax и находит двойной вопросительный знак (или несколько вопросительных знаков), он автоматически предполагает, что вы пытаетесь использовать jsonp.Когда вы устанавливаете тип содержимого вручную, он игнорирует вопросительные знаки.

Поэтому, чтобы избежать проблемы, используйте contentType:

$.ajax(
    url: "your-url.php",
    dataType: "json",                 // what you expect the server to return
    contentType: "application/json",  // what you are sending
    ...
);

Для справки:

jQuery Bugtracker: $ .AJAX ИЗМЕНИЛ СОДЕРЖАНИЕ ПОЧТЫ, ЕСЛИ ВКЛЮЧАЕТ "??"(2 вопроса)

Надеется, что это спасет кого-то еще от часов отладки ...

5 голосов
/ 18 апреля 2011

Если вы не собираетесь форматировать значение «data» как допустимую строку запроса HTML, вам не следует предварительно его форматировать. Как вы заметили, если вы не вызываете «JSON.stringify ()», то это работает. Это потому, что библиотека уже знает, как с этим справиться.

Теперь, если вы хотите отправить свою строку JSON в качестве самого параметра в код на стороне сервера, который ожидает декодировать некоторый JSON, вам необходимо установить его в качестве параметра:

    $.ajax(url, {
      // ...
      data: { jsonParam: jsonData },
      // ...
    });

Теперь ваш сервер увидит HTTP-запрос с параметром «jsonParam», и его значением будет ваша строка в формате JSON.

2 голосов
/ 11 августа 2017

Поскольку ни один из существующих ответов не упоминал об этом. Вы можете решить эту проблему, добавив

jsonp: false

к вашей настройке ajax-запросов.

2 голосов
/ 26 февраля 2013

Я думаю, что вы ищете ответ, установив jsonp: false в опциях вызова AJAX.У меня была точно такая же проблема, и я решил ее.

Прочтите ответ на этот похожий вопрос для получения более подробной информации: Опубликовать данные, переопределяемые с момента обновления с jQuery 1.4 до 1.5

2 голосов
/ 18 ноября 2012

Точно такая же проблема с jQuery 1.71, двойным знаком вопроса и вставкой какой-то сумасшедшей строки.

Удалось исправить это, удалив

dataType: 'JSON'

из команды ajax, и она волшебным образом остановилась.делает это.

1 голос
/ 27 ноября 2015

Я столкнулся с той же проблемой.Указание «contentType»: «application / json; charset = utf-8» решает эту проблему.

jQuery.ajax({
    "url": url,
    "data": JSON.stringify(payload),
    "type": "POST",
    "dataType": "json",
    "contentType":"application/json; charset=utf-8",
    "success": function(data) {

    },
    "error": function(jqXHR, textStatus, errorThrown) {

    }
});
1 голос
/ 06 июня 2012

У меня была такая же проблема.Экранирование значений с помощью encodeURIComponent сделало свое дело!

1 голос
/ 04 ноября 2011

У меня такая проблема в 1.5.2. Это ошибка jQuery: http://bugs.jquery.com/ticket/8417. Вы можете обновить до 1.6.4 или сделать так: В jQuery функция "jQuery.ajaxPrefilter" изменено:

var dataIsString = ( typeof s.data === "string" );

от

var inspectData = s.contentType === "application/x-www-form-urlencoded" &&
        ( typeof s.data === "string" );

и изменил эту переменную в нижеследующем условии "if" следующим образом:

if ( s.dataTypes[ 0 ] === "jsonp" ||
        originalSettings.jsonpCallback ||
        originalSettings.jsonp != null ||
        s.jsonp !== false && ( jsre.test( s.url ) ||
                dataIsString && jsre.test( s.data ) ) ) {
                inspectData && jsre.test( s.data ) ) ) {

Я взял это исправление в форме jQuery 1.6.4.

1 голос
/ 18 апреля 2011

Это звучит как проблема кодирования.Если ваши данные не в формате UTF-8 (например, MS Word или что-то еще), это может произойти.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...