I am able to consume the php endpoint from postman. I try to do the same from angular post, I get this error - Http failure during parsing for. Even though everything looks perfect to me, the problem is surprising. Here is my snippet
php file
<?php
header('Access-Control-Allow-Origin: *');
// check for post
if ($_SERVER['REQUEST_METHOD']=='POST') {
$name = $_POST['name'];
$email = $_POST['email'];
$subject = $_POST['subject'];
$message = $_POST['message'];
// include db connect class
require_once __DIR__ . '/db_connect.php';
// connecting to db
$conn = new db_CONNECT();
$cone=$conn->con;
//escpae the strings to be inserted to DB
$escapedname = mysqli_real_escape_string($cone, $name);
$escapedemail = mysqli_real_escape_string($cone, $email);
$escapedsubject= mysqli_real_escape_string($cone, $subject);
$escapedmessage = mysqli_real_escape_string($cone, $message);
// mysql inserting a new row
$sql = "INSERT INTO contacts(name, email, subject, message) VALUES ('$escapedname', '$escapedemail', '$escapedsubject', '$escapedmessage')";
// $result= $cone -> query($sql);
// $affected = $cone -> affected_rows;
if (mysqli_query($cone,$sql)) {
echo "Information saved successfully.";
} else {
echo "Not successful";
}
} else {
echo "Some field missing.";
}
?>
here is the angular snippet
saveContactDetails = function () {
this.proceed = true;
this.success = false;
const myheader = new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded');
data.append('name', this.contactDeJson.name);
data.append('email', this.contactDeJson.email);
data.append('subject', this.contactDeJson.subject);
data.append('message', this.contactDeJson.message);
this.http
.post('http://localhost:80/'+'api/create_contact.php', data.toString(), {headers: myheader})
Please why am I getting this error
{"headers":{"normalizedNames":{},"lazyUpdate":null},"status":200,"statusText":"OK","url":"http://localhost/api/create_contact.php","ok":false,"name":"HttpErrorResponse","message":"Http failure during parsing for http://localhost/api/create_contact.php",
I believe the issue is that your angular script is expecting a json response (the default responseType), but not receiving the correct headers or data. In stead of just echoing out your result in php, I would make a function that can handle sending the response. Something like this:
function sendJsonResponse(data, status = 200) {
header('Content-Type: application/json', true, status);
echo json_encode($data);
exit();
}
In stead of of doing this:
echo "Not successful";
You can now do this:
sendJsonResponse("Not successful", 500);
This should give you more valuable information in the frontend. And the response should now be formatted correctly, and no longer produce the parse error in angular that you are getting now.
I believe you are trying to send some query parameters using data variable. You could actually send a JS object as the parameters. Try the following
private saveContactDetails() {
this.proceed = true;
this.success = false;
const myheader = new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded');
const data = {
'name': this.contactDeJson.name,
'email': this.contactDeJson.email,
'subject': this.contactDeJson.subject,
'message': this.contactDeJson.message
}
this.http.post('http://localhost:80/'+'api/create_contact.php', { params: data }, { headers: myheader })
}
Related
If I call the script on browser it does send email to my domain email. Anyway I'm trying to send some contact email from angular 7 apps. I did use HttpClient post and try to send the data as JSON. (Apache server PHP -v 5.6)
I have tried to send the data with URL like mail.php?param1="info#test.test"¶m2="Test email". I did not have any luck. I tried file_get_contents("php://input"); no luck either.
<?php
echo("called");
$postdata = file_get_contents("php://input");
$request = json_decode($postdata);
header('Content-type: application/json');
header("Access-Control-Allow-Origin: *");
header('Access-Control-Allow-Headers: X-Requested-With, content-type, access-control-allow-origin, access-control-allow-methods, access-control-allow-headers');
// Sanitize.
// $title = $_GET['title'];;
// $message = $_GET['message'];;
// $name = $_GET['name'];;
// $from = $_GET['from'];;
$title = $request->title;
$message = $request->message;
$name = $request->name;
$from = $request->from;
$to = "info#test.com";
// Sending email
if(mail($to, $title, $message, $name)){
echo 'Your mail has been sent successfully.';
} else{
echo 'Unable to send email. Please try again.';
}
?>
Here is my Angular Service
export class PollServiceService {
PHP_API_SERVER: string = "/api";
constructor(private http: HttpClient) {
}
public SendEmail(e: any): Observable<any>{
var tmp1 = "/?title=" + e.title + "&message=" +e.message + "&name=" +e.name + "&from=" + e.from ;
return this.http.post<any>(`${this.PHP_API_SERVER}/mail.php`, e);
}
}
I do call the SendEmail(e: any) method on the form. Anyway it does not seem to do to anything. I'm suspect that the php file does not get called at all from the script. Thanks in advance guys.
Your SendEmail function returns an Observable.
You have to subsribe to this Observable in order to make the call happen.
So you should do something like that in a function in your component:
this.pollServiceService.SendEmail(e).subscribe(res => {
// here you can do whatever you want with the result of the call
});
this function should then be called from your form.
I am trying to send a JSON array to the web server. I have looked at several examples online i.e. https://www.youtube.com/watch?v=aTj0ZLha1zE&t and Saving CoreData to a Web Server with Swift 3.0 that have demonstrated how to parse data but I am struggling to achieve this.
Below is my function which should send the data to the server:
func sendRecordToServer() -> [Record] {
let fetchRequest = NSFetchRequest<NSDictionary>(entityName:"Record")
fetchRequest.resultType = .dictionaryResultType
do {
let records = try context.fetch(fetchRequest)
if let jsonData = try? JSONSerialization.data(withJSONObject: records, options: []) {
// jsonData is a byte sequence, to view it you would need to convert to string
print(String(bytes: jsonData, encoding: String.Encoding.utf8))
let URL_SAVE_DATA = URL(string: "http://localhost/api/postdata.php")
let request = NSMutableURLRequest(url: URL_SAVE_DATA!)
request.httpMethod = "POST"
request.httpBody = jsonData
let task = URLSession.shared.dataTask(with: request as URLRequest){
data, response, error in
guard let data = data, error == nil else {
// check for fundamental networking error
print("error=\(String(describing: error?.localizedDescription))")
return
}
let responseString = String(data: data, encoding: .utf8)
print("responseString = \(String(describing: responseString))")
}
task.resume()
}
} catch {
print("Error fetching data from CoreData")
}
return records
}
After encoding the data to JSON, it prints out like this:
Optional([["record_id": 8EC9C1C9-7DD4-4343-B7CC-E4615FDDA150, "name": John ], ["record_id": 7EEA551D-9432-4737-99FB-6BFCF3A92D21, "name": Fred Smith]])
However as I try parsing it though to the server I get this and nothing get sent to the server:
responseString = Optional("")
Update:
Following up from the comment below here is what my posdata.php looks like:
<?php
//creating response array
$json = file_get_contents('php://input');
//echo $json shoulkd show the json string
$array = json_decode($json, true);
// var_dump($arr) should show the array structure
$response = array();
if($_SERVER['REQUEST_METHOD']=='POST'){
//getting values
$record_id = $_POST['record_id'];
$name = $_POST['name'];
//including the db operation file
require_once '../includes/DbOperation.php';
$db = new DbOperation();
//inserting values
if($db->createTeam($record_id, $name)){
$response['error']=false;
$response['message']='Record added successfully';
}else{
$response['error']=true;
$response['message']='Could not add record';
}
}else{
$response['error']=true;
$response['message']='You are not authorized';
}
echo json_encode($response);
DBOperation:
<?php
class DbOperation
{
private $conn;
//Constructor
function __construct()
{
require_once dirname(__FILE__) . '/Config.php';
require_once dirname(__FILE__) . '/DbConnect.php';
// opening db connection
$db = new DbConnect();
$this->conn = $db->connect();
}
//Function to create a new user
public function createTeam($record_id, $name)
{
$stmt = $this->conn->prepare("INSERT INTO record (record_id, name) values (?, ?)");
$stmt->bind_param("si", $record_id, $name);
$result = $stmt->execute();
$stmt->close();
if ($result) {
return true;
} else {
return false;
}
}
}
I am trying to set a CRUD system with Angular2 and MySQL and PHP, I can get my data with this code:
getClients(){
this.http.get('http://localhost/Angular%20tests/pr1/getClients.php')
.subscribe(res=>this.clients=res.json(),
error=> alert("Error get clients"),
()=> console.log("Get clients completed..."));
}
But for sending the data to the server, I don not understand were is my error, The first three instructions are giving the correct values of my entries.
onPersonneF(f:NgForm){
console.log(f.value);
console.log(JSON.stringify(f.value));
console.log(f.valid);
// test for the post
let headers = new Headers({'Content-Type': 'application/json'});
let options = new RequestOptions({headers: headers});
this.http.post('http://localhost/Angular%20tests/pr1/insertClient.php', JSON.stringify(f.value), options);
}
And the code of my php file is:
<?php
// for: Blocage d'une requĂȘte multi-origines (Cross-Origin Request)
header("Access-Control-Allow-Origin: *");
try {
$pdo = new PDO("mysql:host=localhost; dbname=test; char=utf8", '****', '****');
} catch (Exception $e) {
echo "Connexion Error".$e->getMessage();
}
$data = json_decode(file_get_contents("php://input"));
//var_dump($data);
echo "**************";
echo $data->nom_client;
echo "**************";
$nom_client = $data->nom_client;
$prenom_client = $data->prenom_client;
$no_order = $data->no_order;
$query = $pdo->prepare("insert into clients values(NULL,'".$nom_client."', '".$prenom_client."', '".$no_order."')");
$query->execute();
$query->closeCursor();
?>
Do not send it as JSON, but using URLSearchParams and headers as application/x-www-form-urlencoded instead.
onPersonneF(f:NgForm){
let body = new URLSearchParams();
// obviously set your correct parameters
body.set('myPropertyName', f.myProperty)
// the rest of data to send...
let headers = new Headers();
headers.append('Content-Type', 'application/x-www-form-urlencoded');
let options = new RequestOptions({ headers: headers });
this.http.post('http://localhost/Angular%20tests/pr1/insertClient.php', body.toString(), options)
.map(res => res.json());
.subscribe(data => console.log(data)) // do subscription in component
}
Then you can reach your data in your php-file... here I simply retrurn the data. Remember to json_encode what you are returning :)
<?php
header("Access-Control-Allow-Origin: *");
$data = file_get_contents("php://input");
echo json_encode($data);
?>
I've got a problem with the file transfer plugin that i can't seem to figure out. My code works when i'm using http, but when I try to upload over https it seems that it doesn't send the parameters to my api but it does reach my api. only the the file is missing, the x-session-token header is present and valid. This is the code i use for uploading the file:
$scope.options = {};
$scope.options.fileKey = "file";
$scope.options.fileName = $scope.img.substr($scope.img.lastIndexOf('/') + 1);
$scope.options.mimeType = "image/jpeg";
$scope.options.headers = {
'x-session-token' : window.localStorage.auth
};
// parameters: source, filePath, options
$cordovaFile.uploadFile("https:/****/api.php/profielpic/", $scope.img, $scope.options, true).then(function(result) {
console.log(result);
$cordovaToast.showShortTop('Uploaden gelukt!').then(function(success) {
$ionicLoading.hide();
$state.go('tab.profiel');
}, function (error) {
$ionicLoading.hide();
$state.go('tab.profiel');
});
}, function(err) {
console.log(err);
$ionicLoading.hide();
});
This is the code i use Server side to see if there's anything:
$app->post('/profielpic/', function () use ($app) {
$auth = new api\src\Auth;
$users = new api\src\Users;
$authdata = json_decode($app->request->headers->get('x-session-token'));
$data = json_decode($app->request->getBody());
$userid = $authdata->userID ;
$session_token = $authdata->session_token;
$userdata = $data->userdata;
$alertsarray = array();
$message = null;
$isValid = true;
$authresult = $auth->authenticate($userid, $session_token);
$imgname = time();
print_r(json_encode($authdata));
print_r(json_encode($_FILES));
print_r(json_encode($_POST));
print_r(json_encode($data));
print_r(json_encode(file_get_contents("php://input")));
/*
if($authresult === true) {
$res = $users->updateUserPicture($userid, $_FILES['file']);
if($res === false) {
$isValid = false;
$message = "Er ging iets mis.";
}else{
$message = $res;
}
}else {
$isValid = true;
$message = $authresult;
}*/
$dataArray = array(
'isValid' => $isValid,
'message' => $message
);
echo ")]}',\n".json_encode($dataArray);
});
but everything is empty with https:// if i upload to http:// it works
Does anyone know why http works but https isn't working? the only case where https isn't working is with file uploads. the rest of my api routes work with https.
It happens on iOS devices and Android devices so the problem is more likely to be with the slim api i'd guess
Api response:
{
"bytesSent": 32889,
"responseCode": 200,
"response": "{\"userID\":\"2\",\"session_token\":\"****"
} {\
"file\":{\"name\":\"modified.jpg?1427448587960\",\"type\":\"image\\/jpeg\",\"tmp_name\":\"\\/tmp\\/phpABKyF2\",\"error\":0,\"size\":37491}}[]null\"\")]}',\n{\"isValid\":true,\"message\":null}",
"objectId": ""
}
Make sure you are using a valid SSL certificate. If your app is reaching the API but not sending the data, its likely that your app has realised the connection is unsafe. It will only send data once it establishes a secure connection to a server it can trust.
A self signed certificate will not be trusted.
I am trying to retrieve data from AngularJS file to PHP file, but I get the error that it's empty.
I can't find any good examples that are dealing with posting data from angularJS to php file and so I need help.
Angularjs file:
angular.module('myApp', ['ajoslin.promise-tracker'])
.controller('help', function ($scope, $http, $log, promiseTracker, $timeout) {
$scope.ph_numbr =/[0-9]+/;
// Form submit handler.
$scope.submit = function(form) {
// Trigger validation flag.
$scope.submitted = true;
// If form is invalid, return and let AngularJS show validation errors.
if (!$scope.toggle || $scope.toggle.length <= 0 || form.$invalid) {
return;
}
// Default values for the request.
$scope.progress = promiseTracker('progress');
var config = {
params : {
//'callback' : 'JSON_CALLBACK',
'name' : $scope.name,
'email' : $scope.email,
'toggle' : $scope.toggle,
'phone' : $scope.phone,
'comments' : $scope.comments
},
tracker : 'progress'
};
$http({
method : 'POST',
url : 'js/contact.php',
data: config,
headers : {'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}
})
.success(function(data, status, headers, config) {
if (data.success) {
$scope.name = null;
$scope.email = null;
$scope.toggle = null;
$scope.phone = null;
$scope.comments = null;
$scope.messages = 'Your form has been sent!';
$scope.submitted = false;
} else {
$scope.messages = 'Oops, we received your request, but there was an error processing it.';
$log.error(data);
}
})
.error(function(data, status, headers, config) {
$scope.progress = data;
$scope.messages = 'There was a network error. Try again later.';
$log.error(data);
});
// Hide the status message which was set above after 3 seconds.
var promise = $timeout(function() {
$scope.messages = null;
}, 3000);
$scope.progress.addPromise(promise);
};
});
php file:
<?php
/*error_reporting(E_ALL);
ini_set('display_errors', '1');
require_once 'js/PHPMailerAutoload.php';*/
ini_set('display_errors', 'On');
error_reporting(E_ALL | E_STRICT);
$data = file_get_contents("php://input");
$postData = json_decode($data);
if (isset($_POST['name']) && isset($_POST['email']) && isset($_POST['toggle']) && isset($_POST['comments'])) {
//check if any of the inputs are empty
if (empty($_POST['name']) || empty($_POST['email']) || empty($_POST['toggle']) || empty($_POST['comments'])) {
$data = array('success' => false, 'message' => 'Please fill out the form completely.');
echo json_encode($data);
exit;
}
$email = trim($_POST['email']);
$subject = trim($_POST['toggle']);
//email address settings
$my_address = "*#yahoo.com";
$headers = "From: ".$email;
$message = "Name: " . $_POST['name'] . "\r\n\r\nMessage: " . $_POST["phone"] . "\r\n\r\nMessage: " . stripslashes($_POST['comments']);
$to = $my_address;
if (isset($_POST['ref'])) {
$mail->Body .= "\r\n\r\nRef: " . $_POST['ref'];
}
if(!$mail->send()) {
$data = array('success' => false, 'message' => 'Message could not be sent. Mailer Error: ' . $mail->ErrorInfo);
echo json_encode($data);
exit;
}
mail($to, $subject, $message, $headers);
$data = array('success' => true, 'message' => 'Thanks! We have received your message.');
echo json_encode($data);
} else {
$data = array('success' => false, 'message' => 'Please fill out the form completely.');
echo json_encode($data);
}
?>
The error message that I get is: "Please fill out the form completely" - which means it doesn't get the values.
My other question is how in the AngularJS do I retrieve the data.success value from the php file?
You seem to be getting the data here:
$data = file_get_contents("php://input");
$postData = json_decode($data);
but then you're using $_POST instead. Perhaps this would work:
if (empty($postData['name']) //etc
It looks like you're accessing data.success appropriately and the value should be set to false as your code currently is.
Additional code review:
If there are errors on the server, it's best to return a status code that indicates that. As is, the server is returning 200 (default), which means everything is OK, even though the request is actually failing. That would eliminate the need for data.success. If the server sends status 200, your .success function will fire. If it returns an error status, like 404, then your .error function would fire instead.
I have doubts about your need of the Content-Type header. You might want to reconsider if that's necessary.
On your Angular form, you ought to nest those $scope properties in an object:
$scope.formData = {
name: '',
email: '',
//etc
}
Then, you can simply pass that directly to your $http call and to reset the values you can simply do $scope.formData = {}.