Invalid json data in request body syntax error yii2

HTTP JSON POST Пытаюсь отправить данные POST запросом с данными упакованными в JSON СоединениеHHTP = Новый HTTPСоединение(Хост); //адрес сервера без http HTTPЗапрос = Новый HTTPЗапрос; ЗаписьJSON = Новый ЗаписьJSON; МассивДанныхJson = Новый Массив; СтруктураДанныхJson = Новый Структура; HTTPЗапрос.АдресРесурса = «/client»; HTTPЗапрос.Заголовки.Вставить(«Authorization», «Basic ***»); HTTPЗапрос.Заголовки.Вставить(«Content-Type», «application/x-www-form-urlencoded»); HTTPЗапрос.Заголовки.Вставить(«Accept», «application/json»); HTTPЗапрос.Заголовки.Вставить(«Connection», «Keep-Alive»); Запрос = Новый Запрос; Запрос.Текст […]

Содержание

  1. HTTP JSON POST
  2. Invalid JSON in API responses #13841
  3. Comments
  4. What steps will reproduce the problem?
  5. What is the expected result?
  6. What do you get instead?
  7. Additional info
  8. Footer
  9. Error Handling ¶
  10. Customizing Error Response ¶
  11. Bad Request error on valid JSON request #14676
  12. Comments
  13. What steps will reproduce the problem?
  14. What do you get instead?
  15. Additional info
  16. В PHP Yii $_REQUEST не может получить данные из внешнего сообщения

HTTP JSON POST

Пытаюсь отправить данные POST запросом с данными упакованными в JSON

СоединениеHHTP = Новый HTTPСоединение(Хост); //адрес сервера без http

HTTPЗапрос = Новый HTTPЗапрос;

ЗаписьJSON = Новый ЗаписьJSON;
МассивДанныхJson = Новый Массив;
СтруктураДанныхJson = Новый Структура;

HTTPЗапрос.АдресРесурса = «/client»;
HTTPЗапрос.Заголовки.Вставить(«Authorization», «Basic ***»);
HTTPЗапрос.Заголовки.Вставить(«Content-Type», «application/x-www-form-urlencoded»);
HTTPЗапрос.Заголовки.Вставить(«Accept», «application/json»);
HTTPЗапрос.Заголовки.Вставить(«Connection», «Keep-Alive»);

Запрос = Новый Запрос;

Запрос.Текст = «ВЫБРАТЬ ПЕРВЫЕ 1
| Контрагенты.Ссылка
|ИЗ
| Справочник.Контрагенты КАК Контрагенты»;

Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
СтруктураИнформации = Новый Структура;

СтруктураИнформации.Вставить(«type», 0);
СтруктураИнформации.Вставить(«name», «Тест3»);
СтруктураИнформации.Вставить(«code», «111»);

Попытка
//Отправляем для обработки на наш сервер
Ответ = СоединениеHHTP.ОтправитьДляОбработки(HTTPЗапрос, ДокументОтвет);

Сообщить(Ответ.КодСостояния);
Исключение
#Если клиент Тогда
Сообщить(ОписаниеОшибки());
#КонецЕсли
КонецПопытки;

В ответа приходит

Я уже всю голову сломал что ни так. Ткните носом где не верно написано.

Теперь ругается на синтаксис:

(14) Мля. Garykom ты попал в точку.
Именно из-за этой хероты и не работало ни черта.
Хотя специально сейчас взял те 5 строчек с описанием API, и там написано что именно через «param=» отправлять!

Источник

Invalid JSON in API responses #13841

What steps will reproduce the problem?

DEBUG=true
Generate any error response from an API.
Notice the unescaped string in the type field.

What is the expected result?

What do you get instead?

Maybe this could be json encoded to ensure those namespace backslashes are escaped. https://github.com/yiisoft/yii2/blob/master/framework/web/ErrorHandler.php#L147

Additional info

Q A
Yii version 2.0.11.2
PHP version 7.0
Operating system N/A

The text was updated successfully, but these errors were encountered:

How do you throw exception? I’ve tried throwing BadRequestHttpException and the response was escaped properly:

Thanks for checking that out. Yours looks right, I must be doing something wrong then.

I’m writing an API and wanted to ensure the only type of error response that ever came out the API was a JSON response, so I customized and configured my own and I suppose this means my implementation is not using the same as Yii’s built-in.

Especially on line 121, however that’s obviously not the case, becuase it seems yours is being run through a json encoder. do you have any advice on where I might find the logic that is handling your response?

Getting the same proper encoding with your code.

Closing the issue since I’m unable to reproduce it.

In reading the docs, I don’t think I ever needed to write my own custom error handler in the first place, I added the following config:

and it’s turning all responses into JSON, even compile problems. However it’s still not encoding properly so I’m wondering if there’s some configuration involved with escaping the JSON or not? I thought I’d seen something about it in the JsonResponseFormatter. I’ll keep looking, if you happen to notice you have some config that might be controlling it on your end, would you mind letting me know? Thanks for your time, I appreciate as always!

I haven’t touched anything about response formatting. Config is pretty much the same as the one in the basic app.

Could it be that your browser is eating double slashes? Can you try something like curl?

well, that was a fantastic idea, I DO see the proper encoding via curl . sorry to have wasted your time like that 😐 I also see now within my XHR plugin there is a «Raw» and «JSON» tab, I see the additional backslashes in the «RAW» tab.

Well, one great thing from all this is I learned I don’t need to write custom error handler, I can simply configure the ‘response’ properly! Thank you again, hope you have a great rest of your day.

© 2023 GitHub, Inc.

You can’t perform that action at this time.

You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.

Источник

Error Handling ¶

When handling a RESTful API request, if there is an error in the user request or if something unexpected happens on the server, you may simply throw an exception to notify the user that something went wrong. If you can identify the cause of the error (e.g., the requested resource does not exist), you should consider throwing an exception along with a proper HTTP status code (e.g., yiiwebNotFoundHttpException represents a 404 status code). Yii will send the response along with the corresponding HTTP status code and text. Yii will also include the serialized representation of the exception in the response body. For example:

The following list summarizes the HTTP status codes that are used by the Yii REST framework:

  • 200 : OK. Everything worked as expected.
  • 201 : A resource was successfully created in response to a POST request. The Location header contains the URL pointing to the newly created resource.
  • 204 : The request was handled successfully and the response contains no body content (like a DELETE request).
  • 304 : The resource was not modified. You can use the cached version.
  • 400 : Bad request. This could be caused by various actions by the user, such as providing invalid JSON data in the request body, providing invalid action parameters, etc.
  • 401 : Authentication failed.
  • 403 : The authenticated user is not allowed to access the specified API endpoint.
  • 404 : The requested resource does not exist.
  • 405 : Method not allowed. Please check the Allow header for the allowed HTTP methods.
  • 415 : Unsupported media type. The requested content type or version number is invalid.
  • 422 : Data validation failed (in response to a POST request, for example). Please check the response body for detailed error messages.
  • 429 : Too many requests. The request was rejected due to rate limiting.
  • 500 : Internal server error. This could be caused by internal program errors.

Customizing Error Response ¶

Sometimes you may want to customize the default error response format. For example, instead of relying on using different HTTP statuses to indicate different errors, you would like to always use 200 as HTTP status and enclose the actual HTTP status code as part of the JSON structure in the response, like shown in the following,

To achieve this goal, you can respond to the beforeSend event of the response component in the application configuration:

The above code will reformat the response (for both successful and failed responses) as explained when suppress_response_code is passed as a GET parameter.

Источник

Bad Request error on valid JSON request #14676

What steps will reproduce the problem?

I have set the JSON parser in my web.php config file :
$config = [
‘id’ => ‘basic’,
‘basePath’ => dirname(__DIR__),
‘bootstrap’ => [ ‘log’ ],
‘components’ => [
‘request’ => [
// . insert a secret key in the following (if it is empty) — this is required by cookie validation
‘cookieValidationKey’ => ‘xxxx’,
‘parsers’ => [
‘application/json’ => ‘yiiwebJsonParser’,
],
],
.
];
But when i send a JSON-RPC request, i get
Bad Request (#400)

Then i have put some code to dump the request from the beginning of index.php:
$URI = print_r($_SERVER[‘REQUEST_URI’],true);
$get = print_r($_GET,true);
$post = print_r($_POST,true);
$hdr = print_r(getallheaders(),true);
$body = @file_get_contents(‘php://input’);
die(«_GET:$get
Headers:$hdr
POST:$post
Uri:$URI
Raw Data:$body»);

‘_GET:Array ( [apiKey] => apikeytest )`

Headers:Array
(
[Host] => localhost
[Accept] => */*
[Connection] => close
[Accept-encoding] => gzip, deflate
[Content-type] => application/json
[User-agent] => EHttpClient
[Content-Length] => 57
)

The raw data seems valid JSON according to an online validator site.
What am i missing?

What do you get instead?

Bad Request (#400) error.

Additional info

Q A
Yii version 2.0.12
PHP version 7.1.7
Operating system Windows 10 Home XAMPP 3.2.2

The text was updated successfully, but these errors were encountered:

Источник

В PHP Yii $_REQUEST не может получить данные из внешнего сообщения

Автор: David Wong
Дата записи

Сцена: Недавно при создании PHP-сервиса мы столкнулись с проблемой. Структура-это YII. Мы отправляем данные через ПОЧТАЛЬОНА и выбираем в качестве режима отправки СООБЩЕНИЕ. Тело имеет три основных варианта 1、форма-данные 2、x-www-форма-url-код 3、необработанный

Когда выбрана форма-данные, данные записи обычно принимаются путем отправки, но когда выбран параметр raw+JSON (приложение/json), данные записи пусты.

В чем причина этой проблемы? Нам нужно начать с принципа реализации YII.

1. Отправляйте данные в формате JSON через curl, такие как код:

Затем на получающем конце получите с помощью $_POST и обнаружите, что печать пуста

Причина в том, что по умолчанию PHP распознает только тип данных стандарта application/x-www.form-url, поэтому он не может его получить и может только проходить через него.

2. Если мы хотим пройти в рамках Yii2

Таким образом, чтобы получить параметры post, переданные в первой части с использованием режима curl JSON, мы обнаружили, что это невозможно, нам нужно установить компонент запроса yii 2.

А потом мы пройдем через это.

Если вы напечатаете $_POST, вы обнаружите, что здесь все еще нет значения. Почему?

Далее мы проверяем исходный код Yii2 с помощью кода.

1. Откройте веб-запрос yii, чтобы найти метод post ():

Значение обнаружения задается параметром $this – > getBodyParam ($имя, $Значение по умолчанию).

Затем найдите этот метод, код выглядит следующим образом:

Выведите $rawContentType = $this – > getContentType (); эту переменную, найдите ее значение: application/json, а затем посмотрите на функцию getContentType ()

То есть, когда мы отправляем запросы curl в формате JSON, $_SERVER[‘CONTENT_TYPE’] имеет значение application/json.

2. Вернувшись к функции getBodyParams () выше, он продолжит выполнение следующего кода:

Анализатор $генерируется из анализатора YIIWEBJSON в анализаторах в приведенной ниже конфигурации компонента запроса, а затем через контейнер.

Таким образом, возвращаемое значение – $parser – > parse ($this – > getRawBody (), $rawContentType); возвращаемое значение – $parser – > parse ($this – > getRawBody (), $rawContentType).

3. Сначала давайте рассмотрим первый переданный параметр, который является функцией $this – > getRawBody (). Код выглядит следующим образом:

С помощью этой функции, возвращаясь к тому, что мы говорили ранее, мы можем пройти

Эти два метода получают данные JSON, передаваемые curl json, yii2 использует второй метод.

Затем мы открываем веб-анализатор yii Json

Здесь вы можете видеть, что переданный JSON преобразуется в массив, а затем Yii:: request – > post (‘имя пользователя’) принимает значение из возвращенного массива.

1. В рамках Yii2 вместо методов $_POST $_GET следует использовать инкапсулированные методы post () и get (), поскольку эти два метода не равны.

2. Когда Yii2 создает api, если он в формате JSON для передачи данных, не забудьте добавить конфигурацию в компонент запроса:

Источник

Автор оригинала: David Wong.

Сцена: Недавно при создании PHP-сервиса мы столкнулись с проблемой. Структура-это YII. Мы отправляем данные через ПОЧТАЛЬОНА и выбираем в качестве режима отправки СООБЩЕНИЕ. Тело имеет три основных варианта 1、форма-данные 2、x-www-форма-url-код 3、необработанный

Когда выбрана форма-данные, данные записи обычно принимаются путем отправки, но когда выбран параметр raw+JSON (приложение/json), данные записи пусты.

В чем причина этой проблемы? Нам нужно начать с принципа реализации YII.

1. Отправляйте данные в формате JSON через curl, такие как код:

php
function http_post_json($url, $jsonStr)
{
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonStr);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
            'Content-Type: application/json; charset=utf-8',
            'Content-Length: ' . strlen($jsonStr)
        )
    );
    $response = curl_exec($ch);
    //$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
 
    return $response;
}


$api_url = 'http://fecshop.appapi.fancyecommerce.com/44.php';
$post_data = [
    'username'     => 'terry',
    'password'     => 'terry4321'
];

Затем на получающем конце получите с помощью $_POST и обнаружите, что печать пуста

Причина в том, что по умолчанию PHP распознает только тип данных стандарта application/x-www.form-url, поэтому он не может его получить и может только проходить через него.

// The first method
$post = $GLOBALS['HTTP_RAW_POST_DATA'];
// The second method
$post = file_get_contents("php://input");

Получать

2. Если мы хотим пройти в рамках Yii2

$username       = Yii::$app->request->post('username');
$password       = Yii::$app->request->post('password');

Таким образом, чтобы получить параметры post, переданные в первой части с использованием режима curl JSON, мы обнаружили, что это невозможно, нам нужно установить компонент запроса yii 2.

'request' => [
            'class' => 'yiiwebRequest',
            'parsers' => [
                 'application/json' => 'yiiwebJsonParser',
            ],
        ],

А потом мы пройдем через это.

$username       = Yii::$app->request->post('username');
$password       = Yii::$app->request->post('password');

Если вы напечатаете $_POST, вы обнаружите, что здесь все еще нет значения. Почему?

Далее мы проверяем исходный код Yii2 с помощью кода.

1. Откройте веб-запрос yii, чтобы найти метод post ():

public function post($name = null, $defaultValue = null)
    {
        if ($name === null) {
            return $this->getBodyParams();
        }

        return $this->getBodyParam($name, $defaultValue);
    }

Значение обнаружения задается параметром $this – > getBodyParam ($имя, $Значение по умолчанию).

Затем найдите этот метод, код выглядит следующим образом:

/**
     * Returns the request parameters given in the request body.
     *
     * Request parameters are determined using the parsers configured in [[parsers]] property.
     * If no parsers are configured for the current [[contentType]] it uses the PHP function `mb_parse_str()`
     * to parse the [[rawBody|request body]].
     * @return array the request parameters given in the request body.
     * @throws yiibaseInvalidConfigException if a registered parser does not implement the [[RequestParserInterface]].
     * @see getMethod()
     * @see getBodyParam()
     * @see setBodyParams()
     */
    public function getBodyParams()
    {
        if ($this->_bodyParams === null) {
            if (isset($_POST[$this->methodParam])) {
                $this->_bodyParams = $_POST;
                unset($this->_bodyParams[$this->methodParam]);
                return $this->_bodyParams;
            }

            $rawContentType = $this->getContentType();
            if (($pos = strpos($rawContentType, ';')) !== false) {
                // e.g. application/json; charset=UTF-8
                $contentType = substr($rawContentType, 0, $pos);
            } else {
                $contentType = $rawContentType;
            }

            if (isset($this->parsers[$contentType])) {
                $parser = Yii::createObject($this->parsers[$contentType]);
                if (!($parser instanceof RequestParserInterface)) {
                    throw new InvalidConfigException("The '$contentType' request parser is invalid. It must implement the yiiwebRequestParserInterface.");
                }
                $this->_bodyParams = $parser->parse($this->getRawBody(), $rawContentType);
            } elseif (isset($this->parsers['*'])) {
                $parser = Yii::createObject($this->parsers['*']);
                if (!($parser instanceof RequestParserInterface)) {
                    throw new InvalidConfigException("The fallback request parser is invalid. It must implement the yiiwebRequestParserInterface.");
                }
                $this->_bodyParams = $parser->parse($this->getRawBody(), $rawContentType);
            } elseif ($this->getMethod() === 'POST') {
                // PHP has already parsed the body so we have all params in $_POST
                $this->_bodyParams = $_POST;
            } else {
                $this->_bodyParams = [];
                mb_parse_str($this->getRawBody(), $this->_bodyParams);
            }
        }

        return $this->_bodyParams;
    }

Выведите $rawContentType = $this – > getContentType (); эту переменную, найдите ее значение: application/json, а затем посмотрите на функцию getContentType ()

public function getContentType()
    {
        if (isset($_SERVER['CONTENT_TYPE'])) {
            return $_SERVER['CONTENT_TYPE'];
        }

        if (isset($_SERVER['HTTP_CONTENT_TYPE'])) {
            //fix bug https://bugs.php.net/bug.php?id=66606
            return $_SERVER['HTTP_CONTENT_TYPE'];
        }

        return null;
    }

То есть, когда мы отправляем запросы curl в формате JSON, $_SERVER[‘CONTENT_TYPE’] имеет значение application/json.

2. Вернувшись к функции getBodyParams () выше, он продолжит выполнение следующего кода:

if (isset($this->parsers[$contentType])) {
    $parser = Yii::createObject($this->parsers[$contentType]);
    if (!($parser instanceof RequestParserInterface)) {
        throw new InvalidConfigException("The '$contentType' request parser is invalid. It must implement the yiiwebRequestParserInterface.");
    }
    $this->_bodyParams = $parser->parse($this->getRawBody(), $rawContentType);
}

Анализатор $генерируется из анализатора YIIWEBJSON в анализаторах в приведенной ниже конфигурации компонента запроса, а затем через контейнер.

'request' => [
    'class' => 'yiiwebRequest',
    'enableCookieValidation' => false,
    'parsers' => [
         'application/json' => 'yiiwebJsonParser',
    ],
],

Таким образом, возвращаемое значение – $parser – > parse ($this – > getRawBody (), $rawContentType); возвращаемое значение – $parser – > parse ($this – > getRawBody (), $rawContentType).

3. Сначала давайте рассмотрим первый переданный параметр, который является функцией $this – > getRawBody (). Код выглядит следующим образом:

public function getRawBody()
{
    if ($this->_rawBody === null) {
        $this->_rawBody = file_get_contents('php://input');
    }

    return $this->_rawBody;
}

С помощью этой функции, возвращаясь к тому, что мы говорили ранее, мы можем пройти

// The first method
$post = $GLOBALS['HTTP_RAW_POST_DATA'];
// The second method
$post = file_get_contents("php://input");

Эти два метода получают данные JSON, передаваемые curl json, yii2 использует второй метод.

Затем мы открываем веб-анализатор yii Json

/**
 * Parses a HTTP request body.
 * @param string $rawBody the raw HTTP request body.
 * @param string $contentType the content type specified for the request body.
 * @return array parameters parsed from the request body
 * @throws BadRequestHttpException if the body contains invalid json and [[throwException]] is `true`.
 */
public function parse($rawBody, $contentType)
{
    try {
        $parameters = Json::decode($rawBody, $this->asArray);
        return $parameters === null ? [] : $parameters;
    } catch (InvalidParamException $e) {
        if ($this->throwException) {
            throw new BadRequestHttpException('Invalid JSON data in request body: ' . $e->getMessage());
        }
        return [];
    }
}

Здесь вы можете видеть, что переданный JSON преобразуется в массив, а затем Yii:: request – > post (‘имя пользователя’) принимает значение из возвращенного массива.

Резюме:

1. В рамках Yii2 вместо методов $_POST $_GET следует использовать инкапсулированные методы post () и get (), поскольку эти два метода не равны.

2. Когда Yii2 создает api, если он в формате JSON для передачи данных, не забудьте добавить конфигурацию в компонент запроса:

'request' => [
            'class' => 'yiiwebRequest',
            'parsers' => [
                 'application/json' => 'yiiwebJsonParser',
            ],
        ],

Пытаюсь отправить данные POST запросом с данными упакованными в JSON

СоединениеHHTP = Новый HTTPСоединение(Хост); //адрес сервера без http

    HTTPЗапрос = Новый HTTPЗапрос;

    
    ЗаписьJSON = Новый ЗаписьJSON;

    МассивДанныхJson = Новый Массив;

    СтруктураДанныхJson = Новый Структура;

    HTTPЗапрос.АдресРесурса = «/client»;    

    HTTPЗапрос.Заголовки.Вставить(«Authorization»,         «Basic ***»);

    HTTPЗапрос.Заголовки.Вставить(«Content-Type»,     «application/x-www-form-urlencoded»);

    HTTPЗапрос.Заголовки.Вставить(«Accept»,             «application/json»);

    HTTPЗапрос.Заголовки.Вставить(«Connection»,         «Keep-Alive»);

        
    Запрос = Новый Запрос;

    
    Запрос.Текст = «ВЫБРАТЬ ПЕРВЫЕ 1

                   |    Контрагенты.Ссылка

                   |ИЗ

                   |    Справочник.Контрагенты КАК Контрагенты»;

    
    ЗаписьJSON.УстановитьСтроку();

    
    Выборка = Запрос.Выполнить().Выбрать();

    Пока Выборка.Следующий() Цикл

        СтруктураИнформации = Новый Структура;

        
        СтруктураИнформации.Вставить(«type»,         0);

        СтруктураИнформации.Вставить(«name»,         «Тест3»);

        СтруктураИнформации.Вставить(«code»,         «111»);

        
        МассивДанныхJson.Добавить(СтруктураИнформации);

        
    КонецЦикла;

    
    СтруктураДанныхJson.Вставить(«client», МассивДанныхJson);

    
    ЗаписатьJSON(ЗаписьJSON, СтруктураДанныхJson);

    
    СтрокаJson = ЗаписьJSON.Закрыть();

    
    Сообщить(СтрокаJson);

    
    HTTPЗапрос.УстановитьТелоИзСтроки(«param=»+СтрокаJson);

    
    ДокументОтвет = «C:1TMP.txt»;

        
    Попытка

        //Отправляем для обработки на наш сервер

        Ответ = СоединениеHHTP.ОтправитьДляОбработки(HTTPЗапрос, ДокументОтвет);

        
        Сообщить(Ответ.КодСостояния);

    Исключение

        #Если клиент Тогда

           Сообщить(ОписаниеОшибки());

        #КонецЕсли  

    КонецПопытки;

В ответа приходит

[{«field»:»code»,»message»:»Необходимо заполнить «Код».»},{«field»:»type»,»message»:»Необходимо заполнить «Юр. лицо».»},{«field»:»name»,»message»:»Необходимо заполнить «Имя».»}]

Я уже всю голову сломал что ни так. Ткните носом где не верно написано.

Понравилась статья? Поделить с друзьями:
  • Invalid image file header 3ds max как исправить
  • Invalid id 4096 maximum id range exceeded как исправить
  • Invalid handle как исправить windows 10
  • Invalid gpu alan wake remastered ошибка
  • Invalid font error