Getting 409 error when calling php from my React application - php

I am trying to call a simple php file from my React application which will send an email with the details from a contact form. For some reason when the React code executes the fetch of the PHP file, it returns a 409. However, if I manually post the URL into another tab it works as expected, and subsequent calls from my React application then work as expected!
This is my React code:
var url = '/backend/sendmail.php?subject=New Website Enquiry&to=info#site.co.uk&msg=' + msg
console.log(url)
console.log('sending')
fetch(url,
{
'headers': {
'Accept': 'text/html',
'Content-Type': 'text/html'
},
'method': 'GET',
})
.then(
(result) => {
console.log(result.status)
if (result.status === 200) {
console.log('success')
this.togglePop();
this.setState({
name: "",
email: "",
phone: "",
message: "",
terms: false,
})
} else {
console.log('failed')
this.setState({ openError: true })
}
},
(error) => {
console.log('ERROR')
console.log(error)
this.setState({ openError: true })
}
)
And this is my PHP file:
<?php
//header("Access-Control-Allow-Origin: *");
header('Content-Type: text/html');
// error handler function
function customError($errno, $errstr) {
error_log($errstr);
http_response_code(500);
}
// set error handler
set_error_handler("customError");
http_response_code(200);
// send email
mail($_GET["to"],$_GET["subject"],$_GET["msg"],"From: donot.reply#site.co.uk","-f donot.reply#site.co.uk");
error_log($_GET["subject"].":\n".$_GET["msg"], 0);
echo 'OK';
?>
I have spent several days trying to figure out why this is happening. My htaccess file seems OK as once I have made one succesful call to the PHP file it works after that!
It's not a CORS issue as the file is on the same domain.
Anyone got any ideas?

You are sending the wrong request to the server, and that's why you get a 409 error. You should encode the URL params before sending a request
const url = '/backend/sendmail.php?subject=New Website Enquiry&to=info#site.co.uk&msg=' + msg;
const encoded = encodeURI(url);
console.log(encoded)
// expected correct URI: "/backend/sendmail.php?subject=New%20Website%20Enquiry&to=info#site.co.uk&msg="
You can read more about it here

Related

Alert function in react native

I have set an alert message on the api script but when it successful run on the frontend wont be able to prompt the alert successful message
here my code, this is the frontend code which expected to return the message from the server
fetch(InsertAPIURL, {
mode:'no-cors',
method: 'POST',
headers: headers,
body: JSON.stringify(Data)
})
.then((response) =>response.json())
.then((responseJson)=>{
Alert.alert(responseJson);
}).catch((error) => {
console.error("Error"+error);
})
here is the backend script code
$register = mysqli_query($CN, $insertuserid);
if ($register) {
$Message = "Member has been registered successfully";
$EncodedData=json_encode($Message);
echo $EncodedData;
}
else {
echo "Server Error... please try latter";
}
after execute the data successful insert into the server but it wont prompt anything hope u guys help, thanks in advance
Backend Php: you write the following below:
//backend php
if(ok){
echo json_encode(array("success"=>1,"messsage"=>"successfully"));
}
else{
echo json_encode(array("success"=>0,"messsage"=>"Error Register"));
}
//frontEnd React
fetch(URL,options).then(res=>res.json()).then(result=>{
if(result.success===1){
//write code successfully
Alert.
}
else{
//write code error register
Alert.
}
});
Alert Doc: https://reactnative.dev/docs/alert#alert
static alert(title, meesage?, buttons?, options?)
Parameters:
NAME
TYPE
DESCRIPTION
title
string
The dialog's title. Passing null or empty string will hide the title.
message
string
An optional message that appears below the dialog's title.
buttons
Buttons
An optional array containing buttons configuration.
options
Options
An optional Alert configuration for the Android.
You can only use string, null, and empty type in the title.
responseJSON is not valid type.
fetch(InsertAPIURL, {
mode:'no-cors',
method: 'POST',
headers: headers,
body: JSON.stringify(Data)
})
.then((response) =>response.json())
.then((responseJson)=>{
Alert.alert(responseJson);
}).catch((error) => {
console.error("Error"+error);
})
to
fetch(InsertAPIURL, {
mode:'no-cors',
method: 'POST',
headers: headers,
body: JSON.stringify(Data)
})
.then((response) =>response.json())
.then((responseJson)=>{
Alert.alert(JSON.stringify(responseJson));
}).catch((error) => {
console.error("Error"+error);
})

React Native uploading Image to php page on server

I have PHP page on a web server to upload image from React Native.
Using Postman method POST, form-data key:avatar value: image_file everything works as expected.
In React Native I tried:
let uploadData = new FormData();
uploadData.append('avatar', uploadUri);
fetch(base_url, { method: 'post,', body: uploadData }).then(
(res) => {
var myresponse = res;
console.log(JSON.stringify(myresponse));
//console.log(res);
}
);
I am getting from server error:
{"type":"default","status":400,"ok":false,"headers":{"map":{"server":"Apache","connection":"Upgrade,
close","content-type":"text/html","vary":"Accept-Encoding,User-Agent","date":"Wed,
20 May 2020 15:29:15
GMT","accept-ranges":"bytes","upgrade":"h2,h2c"}},"url":"http://www./uploadImage.php","_bodyInit":{"_data":{"size":10154,"offset":0,"blobId":"D8041FEE-0479-4CD5-8438-4EFD737561DE","type":"text/html","name":"uploadImage.php","__collector":{}}},"_bodyBlob":{"_data":{"size":10154,"offset":0,"blobId":"D8041FEE-0479-4CD5-8438-4EFD737561DE","type":"text/html","name":"uploadImage.php","__collector":{}}}}
Than I tried using axios:
let uploadData = new FormData();
uploadData.append('avatar', uploadUri);
axios.post(base_url, uploadData).then((res) => {
console.log(res);
});
I get this response from the server:
"error": true,
"message": "No file was sent!",
"status": "error",
It is failing on: if($_FILES['avatar']), in PHP.
I have no idea what to do any more, again in Postman everything works fine as expected.
Does anybody have any idea what to do?
I tested it again and it is to be a problem with the URI that I am sending, for sure.
ie. if I look in Postman the request that I am sending:
avatar=#/Users/......image.jpg
and in React Native I am sending:
"avatar","file:///Users/.....image.jpg
By the way, I am using expo-image-picker to select the image.
It looks like this did the work..
let body = new FormData();
//Appending file to body
body.append('avatar', {
uri: uploadUri,
type: 'image/jpeg', //This is the file type .. you can define according to your requirement
name: 'avatar.jpg', //File name you want to pass
});
//Service call
fetch(base_url, {
method: 'POST',
headers: new Headers({
'Content-Type': 'application/x-www-form-urlencoded',
}),
body: body,
})
.then((res) => res.json())
.then((responseJson) => {
//GET RESPONSE SUCCESS OF FAILURE
console.log(JSON.stringify(responseJson));
})
.catch((error) => {
//ERROR
console.log(JSON.stringify(error));
});

Ajax Call Back and Laravel

I have created an API which my AJAX post send values to it. AJAX does post and my laravel API does process the values. My issues is with the callback returning the value back to my AJAX post. My AJAX doesn't return the results in the success section when I do console log. I would like the results from my api to can use data to make my condition. At the moment, the console log doesn't even return a value. But in my chrome inspector under preview it shows the response from my API but not in the success section.
AJAX
var fname = "Joe";
var lname = "Test";
var processUrl = "api.example.com/z1";
$.ajax({
type: 'POST',
url: processUrl,
data: {"name": fname,"surname": lname},
dataType: 'json',
success: function(res){
console.log(res);
if(res.length >= 1){
$('#display').val(res.name);
}
}
});
PHP
public function checkResults(Request $request){
$name = $request->name." ".$request->surname;
$result = array();
$result['name'] = [$name];
return response()->json($result,201);
}
For first it will be good to return with 200 OK response code (instead of 201).
Note: If you want to just immediately get the answer for your question only, you can see the last part of this answer (usage of "done/fail" construct instead of "success/error").
Additional:
There is many patterns which are used by Client(Frontend)<->API<->Server(Backend) developers.
Approximately all APIs built without any 500 server error codes. But there is exists also many differences between APIs structures.
One of them is to send response like this (this is the only one example of response):
return response()->json([
'success' => true, // true or false
'message' => "Message about success!",
], 200); // 200, 401, 403, 404, 409, etc
The other approach is to always sending 200 OK, but message can be also about error:
return response()->json([
'success' => false, // true or false
'code' => 404,
'message' => "Resource not found!",
], 200);
This kind of methods will written under try{}catch() and will return only 200, but that messages can imitated also as an error (as in example).
The other (appropriate approach for you) is to change your Frontend AJAX functionality like this:
$.ajax({
type: 'POST',
url: processUrl,
data: {
{{--_token: "{{ csrf_token() }}",--}}
name: fname,
surname: lname
},
dataType: 'json'
}).done(function(res) {
console.log(res);
if(res.length >= 1) {
$('#display').val(res.name);
}
}).fail(function(jqXHR, textStatus, errorThrown) {
console.log("Error: " + textStatus);
});
AJAX .done() function replaces method .success() which was deprecated in jQuery 1.8. This is an alternative construct for the success callback function (like before: "success: function(){...}").
AJAX .fail() function replaces method .error() which was deprecated in jQuery 1.8. This is an alternative construct for the complete callback function (like before: "error: function(){...}").
Note: .error() callback is called on HTTP errors, but also if JSON parsing on the response fails. This is what's probably happening if response code is 200/201 but you still are thrown to error callback.
I believe this is happening because you are sending status code 201 (Created), but you need to send status code 200 (OK) to trigger the success callback.
public function checkResults(Request $request){
$name = $request->name." ".$request->surname;
$result = array();
$result['name'] = [$name];
return response()->json($result,200);
}
I couldn't find it specifically in the jQuery docs, but this SO question addresses it.
Due to the asynchronous nature of Ajax calls, do not put them in the normal execution flow of your program. See this post to get more insight.
A quick fix for your problem is to include the ajax call in a function and call that function anytime you want to interact with the server asynchronously.
var fname = "Joe";
var lname = "Test";
var processUrl = "api.example.com/z1";
ajaxCall();
function ajaxCall() {
$.ajax({
type: 'POST',
url: processUrl,
data: {"name": fname,"surname": lname},
dataType: 'json',
success: function(res){
console.log(res);
if(res.length >= 1){
$('#display').val(res.name);
}
},
error: function() {
console.log('error');
}
});
}
In addition, include an error function in the ajax call settings to handle cases where the ajax request fails. See this answer for alternative styles of doing this.

After a JQuery Ajax call, unable to remove "X-Requested-With" from subsequent Slim URL redirect request headers

After a JQuery AJAX call, all subsequent Slim redirects includes "X-Requested-With:XMLHttpRequest" in the request header. As a result, content of the redirected page is being returned in the background in the response, but browser is not redirecting to the intended URL. Not sure what I am doing wrong here.
My Ajax call is given below (this is an implementation of: https://developers.google.com/+/web/signin/server-side-flow):
function signInCallback(authResult) {
if (authResult['code']) {
// Hide the sign-in button now
$('#signinButton').attr('style', 'display: none');
// Send the code to the server
$.ajax({
type: 'GET',
url: '../google/',
contentType: 'application/octet-stream; charset=utf-8',
success: function(result) {
console.log(authResult['code']);
},
data: "gplustoken="+authResult['access_token'],
error: function (request, status, error) {
console.log("Error");
}
});
} else if (authResult['error']) {
// There was an error.
}
}
}
PHP Slim URL redirect code is given below:
$app->redirect($app->urlFor("home"));
For the context of above line, kindly see:
https://github.com/TheRosettaFoundation/SOLAS-Match/blob/master/ui/RouteHandlers/UserRouteHandler.class.php#L413
I tried to remove the 'X-Requested-With' from the request header in the PHP/Slim Code as below, but it did not work either.
$isAjaxRequest = $app->request->headers->get('X-Requested-With') == 'XMLHttpRequest';
if ($isAjaxRequest) {
if (isset($_SERVER['HTTP_X_REQUESTED_WITH']))
{
unset($_SERVER['HTTP_X_REQUESTED_WITH']);
//$app->request->headers->set('X-Requested-With','');
$app->redirect($app->urlFor("home"));
}
} else
$app->redirect($app->urlFor("home"));
Any help to resolve this issue is much appreciated.
Looking at the Slim docs for the Http Headers object, you should be able to achieve this by calling the remove method:
$app->request->headers->remove('X-Requested-With');

Laravel AJAX can't get response

I'm working with the Laravel framework and I'm making an AJAX request to send an email. The request works fine and the mail is sent, the problem is I can't get the server response if the mail has been sent successfully or not.
Here's the code (short version) wich is located under views/contact/mail.blade.php :
if( mail($to, $subject, $body,$headers) ) {
$data = array( 'text' => Lang::line('contact.mail-success')->get() );
return Response::json($data);
} else {
$data = array( 'text' => Lang::line('contact.mail-error')->get() );
return Response::json($data);
}
and here's the jquery :
$('#contact-form').submit(function() {
var request = $.ajax({
url: BASE+'/contact',
type: 'post',
data: { name: $('#name').val(), mail: $('#email').val(), message: $('#msg').val() },
dataType:"json",
success: function(data){
var message = $.parseJSON(data);
alert(message.text); // here I get the "cannot read property of null" in the console log
}
});
return false;
});
What am I doing wrong? Thanks for your help.
Since Laravel sends the correct headers with Response::json there's no need to parse the JSON in your Javascript, simply change the line
var message = $.parseJSON(data);
to
var message = data;
You shouldn't return Response::json() from a view file, the view are supposed to echo whatever output generated from the view but in this case you need to return the response from the route itself, as json would also include header information.
While sending a response in form of JSON must be encoded using json_encode(); in PHP. after successful reach of done method then parse the object as JSON.parse();
Example :
Modify the line in php file as
return response()->json(json_encode($data));
add the line in javascript files as
done(function (data){
console.log(JSON.parse(data));
console.log(data.text);
});

Categories