简体   繁体   中英

How to get the JSON content of a HTTP Post request?

I want to send a JSON file from my Unity application to my Laravel backend. It seems there is something wrong with my post request but I can't figure out what it is.

Sending the request using Unity

public void SendRequest()
        {
            // serializable struct
            OfferData data = new OfferData(OfferSize.JUMBO, OfferType.AD, 50, 10);

            StartCoroutine(RequestHandler.Post(API_URL + "shop/store", JsonUtility.ToJson(data), (response) =>
            {
                if (response == null)
                {
                    return;
                }
                // success
                Debug.Log(response);
            }));
        }

The JSON:

{
"size":3,
"type":1,
"gold":50,
"gems":10
}

The post function in the RequestHandler:

public static IEnumerator Post(string uri, string data, Action<string> response)
        {
            UnityWebRequest webRequest = UnityWebRequest.Post(uri, data);
            webRequest.SetRequestHeader("Content-Type", "application/json");

            yield return webRequest.SendWebRequest();

            if (webRequest.isNetworkError)
            {
                Error(webRequest.error);
                response(null);
            }
            else
            {
                response(webRequest.downloadHandler.text);
            }
        }

If I'm sending the UnityWebRequest with Laravel will send a success response, however, the printed array (see below) is just empty. Laravel can not encode the JSON.

Receiving the request in Laravel

This is where the HTTP Post request is being accessed in my controller function:

public function store(Request $request)
{
    Log::debug($request->json()->all());
}

Which produces the expected result when using Postman:

array ('size' => 3, 'type' => 1, 'gold' => 50, 'gems' => 10)

Sending a similar request with the same JSON using Unity:

array ()

When I use $request->getContent() I can actually see my data. Why is the array empty?

Successful request header

The request header when sent from Postman:

{
"content-type": "application/json",
"user-agent": "PostmanRuntime/7.21.0",
"accept": "*/*",
"cache-control": "no-cache",
"postman-token": "d8f323fc-f2c8-49b8-a023-2955122fa20e",
"host": "127.0.0.1:8000",
"accept-encoding": "gzip, deflate",
"content-length": "119",
"cookie": "XSRF-TOKEN=eyJpdiI6IkRyU1RqSkppcVdyUmpuVHI2Ym55XC9RPT0iLCJ2YWx1ZSI6ImQrc1QrOTcyWE1GSXM3SGQrVlBsTG1lZ0dXd1FCQlRPellTQm83Z0FkWFc0UktjUW9PNHRqS3B3Z2Rya1ZZS2IiLCJtYWMiOiIxMmNlZTFiODc2MTlmNmVhYjI3ZGI1MTQ1NTM2MGFjODQ4YjZhNzdlMmM4NWQwM2NiYzk1MjkzYzNiYjBmNTA5In0%3D; recludo_session=eyJpdiI6ImFLcUdCdU1WU2JzazNEaEFyaGoxbnc9PSIsInZhbHVlIjoiT1VtNzl4XC9HMW5reTdKUGNDdlBXMVdLK3hMNFR3Q2JxMzA1RVY3NWdVdmV5akJhbnBKeU9YdU5JSmdPdGYyNWUiLCJtYWMiOiI4MWJjOGVhMTcxNDI3M2VjNTU0MDc3NmNkZDU0NjZlMzhmYWI1MjRlZGNlZjhhNGEyNmNjMmY3YThiMzAyODNhIn0%3D",
"connection": "keep-alive"
}

Faulty request header

The request header when sent from Unity:

{
"host": "127.0.0.1:8000",
"user-agent": "UnityPlayer/2019.2.8f1 (UnityWebRequest/1.0, libcurl/7.52.0-DEV)",
"accept": "*/*",
"accept-encoding": "deflate, gzip",
"cookie": "XSRF-TOKEN=eyJpdiI6IlJhZE52emU1Z3hYUnVOWmtMbEdZa0E9PSIsInZhbHVlIjoibkdabkhZVnM1ZUYwSklvMzYrSHVLQ0Q5Y2NvRlVTMEhJOHpqMGFCSEZLZVQwd2NnT3NrUmNrXC9cL2Z4XC92M0J0QSIsIm1hYyI6Ijg4ZDUwZDQ4MWQ3OWM3ZjNlOTcxOWE3NzMxYjI1MmQ3NGQ2YzgwMWQ2MDE2YTQ5NTI3NWQ3MTg2ODM4NjMxY2UifQ%3D%3D; recludo_session=eyJpdiI6InoyMktDN3ByR1hYR0tHWCtvdmhOckE9PSIsInZhbHVlIjoiamZJVnlDbVYwZkdBU1wvMXhMeG1sWU5LdDY0d0NnQ0VucE1OK05UNDhUOG1Ya2o5ZUJIcFdaSktuakcrQjJqN1QiLCJtYWMiOiI1YTc5YTE5NDNhNjY5NWRlYzlmMDlkOGIyMWRiYTAzYzMwZTkwNzAzYjBhNTA2OGViOTUyOTlkYzMzYWJlMjA3In0%3D",
"content-type": "application/json",
"x-unity-version": "2019.2.8f1",
"content-length": "215"
}

What am I missing? Please let me know if you need any more information.

The UnityWebRequest.Post send urlencoded data like

  1. uri The target URI to which form data will be transmitted.
  2. postData Form body data. Will be URLEncoded prior to transmission.

you should need to decode the content using urldecode method in php. Like

$decoded = urldecode($request);

to parse json to object:

$data = json_decode($decoded);

to get attribute of json.

$data->{attribute};

I'm still not sure why it doesn't work out of the box but I figured out how to fix this issue.

Add a raw upload handler to the UnityWebRequest :

UnityWebRequest webRequest = UnityWebRequest.Post(uri, data);

// Fix: Add upload handler and pass json as bytes array
webRequest.uploadHandler = new UploadHandlerRaw(Encoding.UTF8.GetBytes(data));

webRequest.SetRequestHeader("Content-Type", "application/json");
yield return webRequest.SendWebRequest();

The JSON data can now be resolved correctly by Laravel.

Sebastian Feistl's answer was the way to go for me, but instead of setting the "Content-Type" for the whole request as "application/json", it would only work if I set it for the uploadHandler:

webRequest.uploadHandler = new UploadHandlerRaw(Encoding.UTF8.GetBytes(data));
webRequest.uploadHandler.contentType = "application/json";

Experimenting with Postman, I found out that the "Content-Length" header is also necessary for this request (at least in my case) and I think that the uploadHandler helps in that regard too, as it sets the content in bytes, therefore the length as well. This is only speculation, though.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM