heldercervantes Posted June 20, 2022 Share Posted June 20, 2022 Hi guys. On my frontend I'm using fetch to submit stuff. Is there a neater way to access this from PHP other than the vanilla json_decode(file_get_contents('php://input')) ? $input doesn't seem to get anything from such a request. Link to comment Share on other sites More sharing options...
kongondo Posted June 20, 2022 Share Posted June 20, 2022 I am assuming you are using fetch() to send an Ajax request to some endpoint. ProcessWire will not recognise Ajax requests without the below in the header: 'X-Requested-With': 'XMLHttpRequest' The this will work: <?php if($config->ajax){ // handle ajax request here $id = (int) $input->some_input_with_id; } 1 Link to comment Share on other sites More sharing options...
Pixrael Posted June 20, 2022 Share Posted June 20, 2022 To make a POST request using the Fetch API, you need to pass the 'method: POST' to the fetch() method as the second parameter: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch | https://reqbin.com/code/javascript/ricgaie0/javascript-fetch-api-example fetch('https://domain.com/api', { method: 'POST' }) .then(resp => resp.json()) .then(json => console.log(json)) 1 Link to comment Share on other sites More sharing options...
heldercervantes Posted June 21, 2022 Author Share Posted June 21, 2022 @kongondo thanks, that certainly makes the detection more elegant. Still have to json-parse the "php://input" to get to the object that I'm passing, though. Example: $fetchVars = json_decode(file_get_contents('php://input'), true); include('./form-processors/'.$fetchVars['form-name'].'.php'); Wouldn't it make sense to have something more processwirey for this as well? Link to comment Share on other sites More sharing options...
Jan Romero Posted June 21, 2022 Share Posted June 21, 2022 Well, you can just send your POST request in such a way that the Json will be available as $input->post['myData'], that is, as FormData or UrlEncoded: fetch('https://example.com', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'X-Requested-With': 'XMLHttpRequest' }, body: new URLSearchParams({ 'myData': JSON.stringify(someObject) }) }); or const formData = new FormData(); formData.append('myData', JSON.stringify(someObject)); fetch('https://example.com', { method: 'POST', headers: { 'X-Requested-With': 'XMLHttpRequest' }, body: formData }); If your object is just a simple key-value affair, you may actually want to send it that way and not as Json at all, because you’ll be able to use the sanitizer methods for each value. With the Json you have to parse it and then sanitize the properties, watch out for properties you didn’t want etc. 4 Link to comment Share on other sites More sharing options...
bernhard Posted June 21, 2022 Share Posted June 21, 2022 Hey @Jan Romero thx for that post ? I've never really understood how such things work and when to use what syntax. When to send a body, when json etc.; Some 3rd party API docs use php://input others use $_GET... Do you have some pointers to make me understand better what's going on and where to use what? Up until now I've managed to get everything working, but sometimes it was just try and error. For example how did you know to use application/x-www... and why are you using URLSearchParams as body? Thank you! Link to comment Share on other sites More sharing options...
Jan Romero Posted June 23, 2022 Share Posted June 23, 2022 @bernhard Admittedly, I had never really paid attention to php://input, so this thread prompted me to google it. As I understand it, that stream always contains the raw request body, so anything could be in there, however only two content-types end up in $_POST and thus also in PW’s $input->post: application/x-www-form-urlencoded and multipart/form-data. For these, in addition to sorting everything into an associative array, PHP also takes care of unescaping the URL encoding. When OP wants to send Json, I’m assuming he quite sensibly declares application/json. PHP doesn’t know this content-type (plus, the whole thing is a nameless Json object, so what would be the key for $_POST’s associative array?), so nothing happens automagically. This answer on SO gives a lengthy overview on how to handle php://input. If you’re asking about the client-side fetch() API, I have to confess I didn’t test the code I posted, but the idea is to create a request with the content-types application/x-www-form-urlencoded or multipart/form-data mentioned above. Indeed, for some reason I thought it would be necessary to specify the former content-type, but it’s actually set automatically when URLSearchParams are used for the request body (at least in Firefox). Likewise, when the body is of type FormData, the default content-type will be multipart/form-data. As for when to send a body, it’s just the HTTP request’s content, so I guess whenever you want to transmit data to the server, i.e. usually with POST (or PUT or something). When dealing with third party APIs you gotta do the weird things they want you to, of course. If it’s your own PHP/ProcessWire site you send requests to, I’d say it doesn’t really matter whether it’s application/x-www-form-urlencoded or multipart/form-data (or URLSearchParams or FormData for that matter), since both deliver keys and values that end up in $_POST/$input->post. In this case I would just use whatever is more convenient to assemble in JS, i. e. if the data actually comes from a HTML form, you can pass the form element to FormData’s constructor and you’re done. Sorry if I’m not telling you anything new here ? Trial and error makes up a large chunk of my modus operandi as well m) 2 1 Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now