I'm trying to rewrite my JQuery $.post()
code via native fetch()
function. And it seems like the only way to do it with PHP server code is using file_get_contents("php://input")
.
I do it like it is shown here and here:
js code:
fetch('/myscript.php', {
method: 'post',
mode: "same-origin",
credentials: "same-origin",
body: JSON.stringify({par1:par1, par2:par2})
}).then(response => response.text())
.then(output => {
// do stuff
});
myscript.php:
$input = json_decode(file_get_contents('php://input'), true);
// do stuff with $input['par1'], $input['par2']
echo $output;
There are two things which makes me worried:
The project has more than one fetch call like this. What if two fetch functions are called simultaneously with two different php script files? They both will access
php://input
at the same time. Won't it lead to a conflict?With
$.post()
I was able to check ifmyscript.php
hasn't been called directly by a hacker with this line of code:if ($_SERVER['HTTP_X_REQUESTED_WITH'] != 'XMLHttpRequest') die('Hack attempt!');
but with the new approach
$_SERVER['HTTP_X_REQUESTED_WITH']
is undefined for some reason. Is there a way to ensuremyscript.php
is called with fetch orphp://input
ensures it automatically?fetch
is pretty modern function, butjson_decode(file_get_contents('php://input'), true)
looks pretty weird and intended for some other use case. Isn't there a better way to fetch data from a php-based server?
CodePudding user response:
- No. Each script invocation has its own
php://input
. - How does that check if it's called by a hacker? Nothing stops a hacker from sending that header. But if you really want it, you can add the header yourself (which is what a hacker would do):
fetch('/myscript.php', {
method: 'post',
mode: "same-origin",
headers: {"X-Requested-With": "XMLHttpRequest"},
credentials: "same-origin",
body: JSON.stringify({par1:par1, par2:par2})
}).then(response => response.text())
.then(output => {
// do stuff
});
- You can send url-encoded parameters instead of JSON. Then PHP will parse them into
$_POST
as with normal forms.
fetch('/myscript.php', {
method: 'post',
mode: "same-origin",
headers: {
"X-Requested-With": "XMLHttpRequest",
"Content-type": "application/x-www-form-urlencoded"
},
credentials: "same-origin",
body: `par1=${encodeURIComponent(par1)}&par2=${encodeURIComponent(par2)}`
}).then(response => response.text())
.then(output => {
// do stuff
});
CodePudding user response:
- Each new process will get a separate "input", there is no risk of conflict.
- You want CSRF tokens. Anyone can send a XMLHttpRequest
- you are comparing oranges to apples. php://input is fine.