0

Im trying to learn REST API and got stuck with decoding data from JS FormData using PUT for example

JS:

newF = async (e) => {
  let formData = new FormData();
  formData.append('key1', 'value1');
  formData.append('key2', 'value2');

  let response = await fetch(api, {
    method: 'PUT',
    body: formData
  });

  let result = await response.json();
  console.log(result)
}
newF()

PHP:

if ($_SERVER['REQUEST_METHOD'] === 'PUT') { 
    $myEntireBody = file_get_contents('php://input'); 
    echo  json_encode($myEntireBody);
}

This is closest that I got but the data returned to me is in strange format:

-----------------------------42245388588346180811466041785

Content-Disposition: form-data; name="key1"



value1

-----------------------------42245388588346180811466041785

Content-Disposition: form-data; name="key2"



value2

-----------------------------42245388588346180811466041785--

I dont know how to get values out of this with keys, I tried decoding/encoding var damp $_PUT in numerous ways and cant get values out.

I tried to follow among others: HTTP protocol's PUT and DELETE and their usage in PHP and Why PHP couldn't get $_POST data from Js FormData fetch? with no luck.

I just want to know how to get values out of JS FormData on PHP side and echo one off them back to JS response to confirm it.

ikiK
  • 6,328
  • 4
  • 20
  • 40
  • Form data isn't JSON. Have you tried to look in $_REQUEST, perhaps? Either that, or send actual JSON from the client. Or use https://stackoverflow.com/a/41959141/5947043 – ADyson Jun 09 '21 at 17:37
  • The format is `multipart/form-data`, not `application/json`. – Evert Jun 09 '21 at 17:51
  • @ADyson I tired that already, cant get it to work, keep getting errors. I dont know what to do after var_dump($_PUT);, i tried to json encode it and send back to se values, just errors. – ikiK Jun 09 '21 at 17:54
  • @Evert Not sure what should I do whit that information. – ikiK Jun 09 '21 at 17:54
  • `I dont know what to do after var_dump($_PUT);`...well what does that command output? That should give you a clue what to do next and how to get the individual data items. If you need help with that, show us what the output looks like. If you get errors, tell us what they are then we can help you with them – ADyson Jun 09 '21 at 17:56
  • @ADyson I get `SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data. ` Same as: `echo json_encode(var_dump($_PUT));` and when I try `echo json_encode($_PUT);` i get same data from my question just wrapped as object. Unusable. – ikiK Jun 09 '21 at 18:05
  • Yes well of course you would, var_dump is just a debugging tool so you can understand what to do next. Ignore the JSON.parse error, that's expected until you return valid JSON alone in the response. Go look at the raw response to the Ajax request in your browser's network tool, then you can see what PHP is actually outputting – ADyson Jun 09 '21 at 18:08
  • `i get same data from my question just wrapped as object`...well yes because JSON is a text format - you would only use that when you want to return something to the browser. $_PUT _should_ be an associative array containing entries for the submitted data, I'd expect. You ought to be able to use it just like $_POST. But show us the var_dump output then we can help to verify it for you – ADyson Jun 09 '21 at 18:10
  • @ADyson Oh didint know about this row resposne. And i get: `array(1) { ["-----------------------------24205680951229711649810835300 Content-Disposition:_form-data;_name"]=> string(195) ""key1" value1 -----------------------------24205680951229711649810835300 Content-Disposition: form-data; name="key2" value2 -----------------------------24205680951229711649810835300-- " }` Trying to get data out of it usual way [] but no luck. – ikiK Jun 09 '21 at 18:11
  • No well that's no use to you, I agree, it isn't what you would want in there. I guess it doesn't know how to parse the multipart data, it's not the same format that's sent when you submit a regular form. – ADyson Jun 09 '21 at 18:32
  • Tbh unless you have a pressing need to use FormData on the client side you're probably better off sending JSON. – ADyson Jun 09 '21 at 18:32
  • @ADyson I have given up on formData and use regular `const data = { key1: 'value1', key2: 'key2' }; fetch("PATH_TO_URL", { method: "POST", body: JSON.stringify(data) })` following this tutorial: https://medium.com/@whole9681/javascript-fetch-api-to-send-data-8c2b1dedaba Now i got response as object of sent data with `echo $json_str;` – ikiK Jun 09 '21 at 18:34
  • Good. You should still be able to use PUT there if you wanted to btw. And if you decode that $json_str you should be able to use the values within it – ADyson Jun 09 '21 at 18:39
  • 1
    @ADyson Yeah Im gonna play around with it, im getting values now finally. Thanks for the time and especially network row response I was wondering how to get that. huge help. Thanks. – ikiK Jun 09 '21 at 18:49
  • 1
    The problem here appears to be that FormData is send as `multipart/form-data` (specified behavior for XHR2, according to https://stackoverflow.com/a/8155863/1427878, so I guess it is the same with `fetch`), but PHP will only automatically parse a request body of that type, when the request method is POST. With a PUT request, you would have to do that part yourself. – CBroe Jun 10 '21 at 07:50
  • But it might be easier to not use FormData in the first place then, and simply assemble your data as `application/x-www-form-urlencoded` in string form, `param1=value1&param2=value2&…`. (Don’t forget to apply proper URL encoding.) Then you can read that via `php://input`, and use `parse_str` on it. – CBroe Jun 10 '21 at 07:51
  • @Cbroe true. Or use JSON as the OP has already done (see last couple of comments) – ADyson Jun 10 '21 at 08:24
  • @CBroe Actualy at first after testing I had strange settings where I sent data like this: `fetch( api + '?edit=' + naziv.value + '&cijena=' + cijena.value + '&kat=' + kat.value + '&id=' + nekid, fetchOptPUT` with fetchOptPUT beaing put method settings and then i managed the fecth it PHP with: if ($_SERVER['REQUEST_METHOD'] === 'PUT') { `if (isset($_GET['edit']) && $_GET['edit'] != "") { $naslov = mysqli_real_escape_string($con, $_GET['edit']); $cijena = mysqli_real_escape_string($con, $_GET['cijena']);` – ikiK Jun 10 '21 at 11:55
  • That's because you placed them in the querystring, not in the request body, so they'd be available through $_GET no matter what the actual HTTP method used was. I wouldn't regard that as strange, particularly - querystring variables can be used alongside the request body in any type of request - querystring and body are separate parts of the request. – ADyson Jun 10 '21 at 11:58
  • @CBroe And this works but makes no sense to send method as PUT but extract data as GET of the body data string. So I tried fromData, in hopes to also be able to send files with POST just for testing. But et end i resorted to JSON and `file_get_contents` – ikiK Jun 10 '21 at 11:58
  • @ADyson Oh yeah you are right that's not the body, yeah but i filtered it with method first, its hack now I see, I have to say im bit confused how to build API's properly :( – ikiK Jun 10 '21 at 11:59
  • "properly" is a bit subjective, but if you're talking about using the RESTful pattern then there are lots of articles around discussing the design principles and how to apply them – ADyson Jun 10 '21 at 12:01
  • 1
    `its hack now I see` ... I disagree. As I said, the querystring and the request body are separate, and both are permissible in any type of HTTP request, alongside each other. It's perhaps unfortunate that PHP decided to name the array which collects the querystring values as $_GET - that is somewhat misleading. But that's the PHP designer's fault and it's just a naming issue. What it's actually _doing_ is perfectly in line with how HTTP is designed to work. If they'd named it $_QUERY or something instead, it would be clearer. – ADyson Jun 10 '21 at 12:02
  • @ADyson Oh yeah I do have a lot of them bookmarked. And lets say I in moment I started to understand how to setup PHP part i get stuck at how to send data from JS, and vice versa, not many tutorials are detailed for both side. But I just find one and getting started. – ikiK Jun 10 '21 at 12:04
  • @ADyson Oh thats great to know! I have review today of this code and was worried its wrong so I was testing other ways. – ikiK Jun 10 '21 at 12:05

0 Answers0