0

I am trying to post user data to a PHP RESTful API from my ionic app. I tried searching for a solution but was of no help. I have created a provider containing a function namely "onSignup(signupForm)" which is being called on button click.

The code is as follows:

signup(username: string,email: string,password: string): void {

let headers = new HttpHeaders();
headers = headers.set("Content-Type","application/json; charset=UTF-8");
let body= {
  name:username, email:email, password:password
};

this.http.post('http://www.something.com/register', JSON.stringify(body), 
{headers: headers})
.subscribe(data => {
  console.log(data);
});
this.storage.set(this.HAS_LOGGED_IN, true);
this.setUsername(username);
this.events.publish('user:signup');
};

The code for the api is as:

<?php
header("Access-Control-Allow-Origin:*");
header("Content-Type: application/json; charset=UTF-8");
require_once '../include/DbHandler.php';
require_once '../include/PassHash.php';
require '.././libs/Slim/Slim.php';

\Slim\Slim::registerAutoloader();

$app = new \Slim\Slim();

/**
* ----------- METHODS WITHOUT AUTHENTICATION ------------------------------- 
     --
     */
     /**
      * User Registration
      * url - /register
      * method - POST
      * params - name, email, password
      */
    $app->post('/register', function() use ($app) {
       file_put_contents("logs.txt","/register Route has been visited");

       // check for required params
       verifyRequiredParams(array('name', 'email', 'password'));

       $response = array();


       // reading post params
       $name = $app->request->post('name');
       $email = $app->request->post('email');
       $password = $app->request->post('password');

       // validating email address
       validateEmail($email);

       $db = new DbHandler();
       $res = $db->createUser($name, $email, $password);

       if ($res == USER_CREATED_SUCCESSFULLY) {
           $response["error"] = false;
           $response["message"] = "You are successfully registered";
       } else if ($res == USER_CREATE_FAILED) {
           $response["error"] = true;
           $response["message"] = "Oops! An error occurred while registereing";
       } else if ($res == USER_ALREADY_EXISTED) {
           $response["error"] = true;
           $response["message"] = "Sorry, this email already existed";
       }
       // echo json response
       echoRespnse(201, $response);
   });

The error I receive is

  1. Failed to load resource: the server responded with a status of 404 (Not Found).

  2. Failed to load http://www.something.com/register: Response for preflight has invalid HTTP status code 404

This API is working perfectly in Postman, but is facing the issue when I am running the app in Chrome.

Is there something I am missing in the API or during the POST call?

Please help. Thanks in Advance.

Edit:

I have added the Network Tab screenshot. This is what I am getting in my Request and Response Headers. I guess there might be a mismatch in the two headers and definitely it can't be a CORS issue because I can make GET calls without any CORS issue.Network Tab Screenshot

Added the console tab screenshot with the errors:

Console error

2
  • 1
    I think it's because you are stringifying your body. Remove JSON.stringify and try again. Commented May 9, 2018 at 1:11
  • @spaceman I did remove the JSON.stringify but it did not work and the results are same. Commented May 9, 2018 at 18:18

2 Answers 2

1

Since it is working from Postman but not your application I would take a good look into CORS. You need to set your headers when a request comes in, for post requests the Angular HttpClient will send an OPTIONS request.

I don't use PHP much, but maybe something like this would work

if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    header('Access-Control-Allow-Origin: *');
    header('Access-Control-Allow-Methods: POST, OPTIONS');
    header('Access-Control-Allow-Headers: Content-Type');
    header('Content-Length: 0');
    header('Content-Type: application/json');
    die();
}

Edit: Since you are using the Slim Framework I assume by your provided code. You can address OPTIONS requests like so as described per the Slim Framework v2 Docs (Not sure what version you are using).

$app->options('/register', function ($app) {
    header('Access-Control-Allow-Origin: *');
    header('Access-Control-Allow-Methods: POST, OPTIONS');
    header('Access-Control-Allow-Headers: Content-Type');
    header('Content-Length: 0');
    header('Content-Type: application/json');
    die();
});

Or you could maybe set the headers like so, as described by https://www.slimframework.com/docs/v2/response/headers.html

$app->response->headers->set('Access-Control-Allow-Origin', '*');
$app->response->headers->set('Access-Control-Allow-Methods', 'POST, OPTIONS');
$app->response->headers->set('Access-Control-Allow-Headers', 'Content-Type');
$app->response->headers->set('Content-Type', 'application/json');
Sign up to request clarification or add additional context in comments.

5 Comments

I have edited the question with a screenshot of the network tab. I do not face any CORS issue while making GET calls to the API. I guess this might be due to difference in the headers. Can you please suggest?
Your screenshot and comments only confirm what I have stated. Which is that "for POST requests the Angular HttpClient will send an OPTIONS request" whereas for GET requests it does not. This is why in the screenshot you are getting a 404 not found.
But when I added the same in the API, it only shows me the request method is POST. So it does not execute the given block. Is there any other way round?
I am not 100% sure what PHP framework version you are using I assumed Slime Framework v2. But I have updated my answer with two possible ways to set the needed headers.
I am using PHP native 5.6 version and you are absolutely correct that I am using Slim framework v2. I have amended the code as you suggested in the API, but did not seem to solve my issue.
0

try this

header('Access-Control-Allow-Origin: *'); 
$dados = file_get_contents('php://input');

you will get a JSON from your angular request...

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.