2

I've a bunch of problems with this matter. Assume following POST (i'm using KnockoutJS to convert my object to json), where i'm posting inside http form data.

$.post('uri', {data: ko.toJSON(data)}, function(response){ // Handle response }, 'json'); 

This is what's happening inside my controller

<?php // 1. My plain input is here, and it's a slash-encoded string, // like { foo: \"bar\"} $input = \Input::get('data'); // 2. Input::json() is empty, maybe because jquery // posts in the http form data instead of posting in payload. $input = \Input::json(); 

So, to get my data out of the Input i have to

$input = stripcslashes($input); dd(json_decode($input)); 

Assume that $.post() call can not be changed, i only want to approach this server side.

I think L4 should provide someway the parsed input, and i think i shouldn't be doing any stripslashes. So, what am i doing wrong?

== EDIT ==

Thanks to fideloper answer and comments, im gonna change something, since there's actually something wrong in the client side $.post (which, anyway, is not the point of this question). So, here's what new javascript will look like (data is still being posted as application/x-www-form-urlencoded):

$.post('uri', ko.toJSON(data), function(response){ // Handle response }, 'json'); 

What's happening now on server side?

dd(\Input::all()); // < --- Contains nothing (array()) dd(\Input::json->all()); // < --- Contains data array, as expected 

What is confusing me is this piece of documentation, from L4 Requests&Input

Note: Some JavaScript libraries such as Backbone may send input to the application as JSON. You may access this data via Input::get like normal.

In this case i can not access data via Input::get. Again: whats wrong?

2
  • I think problem is ko.toJSON(data). Try send data without using toJSON method. Commented Dec 4, 2013 at 13:13
  • I won't add this as an answer because you explicitly said no client side modifications, but I'd just set the processData parameter to false in the ajax request. api.jquery.com/jQuery.ajax Commented Dec 4, 2013 at 13:13

2 Answers 2

1

Solution ( I think :D ):

Use:

$input = json_decode( \Input::get('data') ); 

Instead of :

$input = \Input::json(); 

Explanation:

The Input::json() method is attempting to grab the body of the request, and it's assuming it's in a JSON-encoded format.

However, the ajax call is not sending encoded JSON as the body, but rather POST parameters (which is not simply a JSON-encoded string).

Therefore, you need to grab the proper POST request parameter ("data", in your case) and decode that, since only the "data" POST parameter is actually a JSON-encoded string.

Edit:

I'm not even sure the above will work. Since jquery is being told the "type" is json, it might actually send a json-encoded body. That could mean the relevant data gets encoded twice - once when toJson() is called, and again when jQuery encodes the data object.

Some investigation will be needed.

Sign up to request clarification or add additional context in comments.

6 Comments

You are right about everything. Anyway, i already tried your solution and it will work only if i stripcslashes the input
Understood. Unfortunately, I'm not sure of any other options. The client-side code is, in fact, "doing it wrong" - there's a clear case and argument for not JSON-encoding twice - if that can give you enough reason to have someone change it. (It sounds like that's not under your control :/ )
I changed a bit of JS code, and edited question with new details.
Interesting - I think you may be misunderstanding how Input::json() differs from Input::get(). A POST request will have a request body that looks like foo=bar&foo2=bar2 (and so on with other parameters). A request with content-type JSON should have a json-encoded body - something like { foo: \"bar\"}. In your code, it therefore makes perfect sense that the POST array (which Input::get() grabs from) is empty, while Input::json returns the json-decoded data. The get() method searches for GET or POST parameters, while json() searches the body for json-encoded content.
Eh, my point is that Input:get should not ONLY be grabbing from POST and GET, since L4 docs states so. As far as i know, Laravel should merge those and work like an abstraction layer built over raw HTTP.
|
0

Since you send an array like the following, this should work:

$_POST = array("data" => array("foo" => "bar")); $input = Input::get('data'); $input = $input["data]"; 

If you want to avoid this, use the following javascript, might recheck http://api.jquery.com/jQuery.post/ (example 1: $.post( "test.php", { name: "John", time: "2pm" } );): I am not sure about the toJson Part, maybe this would even work without toJson.

$.post('uri', ko.toJSON(data), function(response){ // Handle response }, 'json'); 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.