Making a Get Request Across Domain & Port Angular2 To PHP - php

After running through this quick example of a GET request from Angular2 to a PHP file I continue to get -
Error 304
I am testing the difference between using node and php for the back end of an angular2 app. I have a simple GET request which is trying to retrieve a small amount of data from a php file.
The request seems to be going fine but the file is not being provided to the app.
304 NOT MODIFIED A conditional GET or HEAD request has been received
and would have resulted in a 200 OK response if it were not for the
fact that the condition evaluated to false.
In other words,
there is no need for the server to transfer a representation of the target resource because the request indicates that the client, which made the request conditional, already has a valid representation; the server is therefore redirecting the client to make use of that stored representation as if it were the payload of a 200 OK response.
CORS
I have CORS allowed inside the express app.js file.
I have CORS allowed in the PHP file.
How can I overcome this issue? I would at least like to console.log the data from the ng2 side.
Code Examples
PHP // Running on Apache port 80 # api.example.com
<?php
header("Access-Control-Allow-Origin: *");
$data = array(
array('id' => '1','first_name' => 'Cynthia'),
array('id' => '2','first_name' => 'Keith'),
array('id' => '3','first_name' => 'Robert'),
array('id' => '4','first_name' => 'Theresa'),
array('id' => '5','first_name' => 'Margaret')
);
echo json_encode($data);
?>
Angular2 // Running on Express Server # localhost:4200
import {Http, Response} from '#angular/http';
import {Injectable, Component } from '#angular/core';
#Component({
selector: 'my-app',
template: `<ul>
<li *ngFor="let person of data">
{{person.id}} - {{person.first_name}}
</li>
</ul>`
})
export class AppComponent {
private data;
constructor(private http:Http){
}
ngOnInit(){
this.getData();
}
getData(){
this.http.get('api.example.com/index.php')
.subscribe(res => this.data = res.json());
}
}
I have tried to modify the getData() function none which have worked. Most recently this,
getData(){
let url = 'api.example.com/index.php';
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
this.http.get(url, options)
.subscribe(res => {
this.data = res.json();
console.log(this.data);
});
}

I had similar issue but have been able to fix it by setting the following headers on my api script;
if (isset($_SERVER['HTTP_ORIGIN'])) {
header("Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}");
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Max-Age: 86400'); // cache for 1 day}
// Since Access-Control headers are received during OPTIONS requests
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD']))
header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']))
header("Access-Control-Allow-Headers: {$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}");
exit(0); }
Hope it helps

Related

React - PHP: How to fix problem of CORS with fetch request for POST request?

I have problem with request POST in fetch function. I make REST API with react and PHP and I get error Access-Control-Allow-Origin is required. I have this header in my web api. This is my code (begin) in PHP:
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: GET,POST,PUT,DELETE");
header("Access-Control-Expose-Headers: access-control-allow-origin");
header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");
header("Content-Type: application/json; charset=UTF-8");
and in React:
//method = POST
//body = {"name":"test","body":"test"}
const apiCall = (url, method, body, resolve, reject) => {
fetch(url, {
method: method,
headers: {
'Content-Type': 'application/json; charset=utf-8'
},
body: JSON.stringify(body)
}).then(resp => {
if(resp.ok) {
resp.json().then(json => resolve(json));
}
else {
reject(resp);
}
});
}
I try to communicate with other server and api - result was the same.
Screen with error in Google Chrome browser:
screen
Please help.
You have to add the CORS MODULE and Proxy in Server.

Connecting PHP Api on server with React expo app localhost. Base url fails

After hours of trying is still can't get my React Expo application (localhost http://192.168.1.113:19006/#/) to connect to my PHP api that is hosted on an external server.
The header of my api file's is as following;
header("Access-Control-Allow-Origin: *");
//header("Access-Control-Allow-Headers: *");
//header("Access-Control-Allow-Credentials: 'true'");
header("Content-Type: application/json");
header("Access-Control-Allow-Methods: POST");
header("Access-Control-Max-Age: 3600");
header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");
When I use postman to connect and test mine /login.php file with the following json body;
POST to: www.URLofAPIlocation.nl/subFolder/api/login.php
{
"email" : "info#email.nl",
"password" : "Password12345"
}
The api returns the JWT token and succes message as expected.
{
"message": "Successful login.",
"jwt": "eyJ0eXA..... ( FULL TOKEN )"
}
But when I try to connect with the following functions within my react native application it try to uses the localhost base url and not the given;
async function postData(url = '', data = {}) {
const response = await fetch(url, {
method: 'POST',
mode: 'cors', // Without cors it fails.
cache: 'no-cache',
// credentials: 'same-origin', // Not sure if needed.
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'POST',
'Access-Control-Max-Age':' 3600',
},
redirect: 'follow',
referrerPolicy: 'no-referrer',
body: JSON.stringify(data)
});
return await response.json();
}
// https://www.URLofAPIlocation.nl/... and https://URLofAPIlocation.nl/ also not working
function login(){
postData('www.URLofAPIlocation.nl/subFolder/api/login.php', {
email : "info#email.nl",
password : "Password12345",
})
// Other option without error catching. (not working..)
// .then((data) => {
// console.log(data); // JSON data parsed by `response.json()` call
// });
.then(response => {
console.log(response)
return response.json()
})
.then(response => {
console.log("End query"+ response);
return response;
})
.catch(err => {
console.log("Error: "+err)
});
}
I'm not sure what I do wrong since every tutorial and documentation I find the exact same setup as I am using.
The error message is as following;
POST http://192.168.1.17:19006/www.URLofAPIlocation.nl/subFolder/api/login.php 404 (Not Found)
It seems like that react expo uses it's own location as the base url and adds the url of the fetch after it. The location of the api is off course without: http://192.168.1.17:19006//. I can't find where to change or remove this, so help would much be appreciated.
Thanks in advance!
Ps because of personal reasons I've hidden the exact web address of the api location and passwords. The api is hosted on an https domain and functions as expected.

Error in ionic app "Request header field is not allowed by Access-Control-Allow-Headers in preflight response."

I have a module in Ionic who calls an api in PHP.
import { LoadingController } from 'ionic-angular';
import { Injectable } from '#angular/core';
import { Http, Headers } from '#angular/http';
import 'rxjs/add/operator/map';
....
getPatrocinios(cidade) {
var headers = new Headers();
headers.append('idCidade', cidade);
let url = 'http://somesite.com/test/index.php';
return this.http
.get(url, { headers: headers })
.map(res => res.json());
}
in PHP module i made this:
<?php
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Allow-Methods: GET,HEAD,OPTIONS,POST,PUT');
header('Access-Control-Allow-Headers: Content-Type, Content-Range, Content-Disposition, Content-Description');
define('CHARSET', 'UTF-8');
define('REPLACE_FLAGS', ENT_COMPAT | ENT_XHTML);
function getHeaders($header_name = null) {
$keys=array_keys($_SERVER);
if(is_null($header_name)) {
$headers=preg_grep("/^HTTP_(.*)/si", $keys);
} else {
$header_name_safe=str_replace("-", "_", strtoupper(preg_quote($header_name)));
$headers=preg_grep("/^HTTP_${header_name_safe}$/si", $keys);
}
foreach($headers as $header) {
if(is_null($header_name)) {
$headervals[substr($header, 5)]=$_SERVER[$header];
} else {
return $_SERVER[$header];
}
}
return $headervals;
}
$id_cidade = getHeaders("idCidade");
...
Using Postman and puting the 'idCidade' in Headers tab, it works fine (status=200), but in the emulator of ionic i have the error: Request header field idCidade is not allowed by Access-Control-Allow-Headers in preflight response.
I tried most solution in stackoverflow, but still not working.
Some extra information:
Ionic Framework: 3.9.2
Ionic App Scripts: 3.1.8
Angular Core: 5.2.9
Angular Compiler CLI: 5.2.9
Node: 8.11.1
Someone to help me?
Request header field idCidade is not allowed by Access-Control-Allow-Headers in preflight response
What response header Access-Control-Allow-Headers Tells the browser is what request headers are allowed in the request. Look at the list that you provided
header('Access-Control-Allow-Headers: Content-Type, Content-Range, Content-Disposition, Content-Description');
The idCidade header is not included in that list.
I had the same problem in an App when i run with Ionic Serve.
If you are using Google Chrome, you can install a CORS extension, enable it, and testing again, in my case, that works.
Heres the extension i used:
https://chrome.google.com/webstore/detail/allow-control-allow-origi/nlfbmbojpeacfghkpbjhddihlkkiljbi
If the problem already exist, we can check other ways

input->post and $_POST are empty in CodeIgniter API calling from Angular 4, what is the right way to make a post request in angular 4

This is the first time I'm making a post method request from Angular to CodeIgniter rest API.
postUsertask(Userid,TaskName)
{
let body ={
userid:Userid, taskname:TaskName
};
console.log(body);
return this.http.post("http://localhost/ci-abc/api/add_task",JSON.stringify(body) )
.map(res => res.json());
}
API method in codeigniter:
function add_task_post()
{
$obj=json_decode(file_get_contents('php://input'));
$taskname = $obj->taskname;
$userid = $obj->userid;
if (!$taskname || !$userid) {
$this->response("Enter taskname and userid to add", 400);
} else
$result = $this->todo_model->add_task($taskname, $userid);
if ($result === 0) {
$this->response("Task could not be added. Try again.", 404);
} else {
$this->response("success", 200);
}
}
Had to include to access the data
$obj=json_decode(file_get_contents('php://input'));
Because the $this->input->post and $_POST were empty and the data recieved from angular was an object so had to be accessed with -> notation. I am curious that this is not the right and ethical way to do this. Also when I didn't put JSON.stringify it gave me Cross Origin Request blocked error so that's why I put it. How should I make POST and PUT request in angular4 to rest API in CodeIgniter?
How do I get rid of CORS error which doesn't let me call the API method, if I can get rid of CORS error then I could also remove JSON.stringify which will send the data as it is and I believe the data should be accessed via input->post or $_POST.
EDIT 2:
These sort of errors while making POST PUT and DELETE API call.
Cross-Origin Request Blocked: The Same Origin Policy disallows reading
the remote resource at http://localhost/ci-abc/api/del_task?taskid=34.
(Reason: CORS preflight channel did not succeed)
EDIT (Perfect Solution):
Found out that the formdata object approach was deprecated so I just included a header in options and included in the API call http.post method which works fine and is much better solution.
constructor(public http:Http) {
let headers = new Headers();
headers.append('Content-Type', 'application/json');
let options = new RequestOptions({ headers: headers });}
createUser(userName)
{
let body = { username:userName};
return this.http.post("http://localhost/ci-abc/api/create_user",body,this.options)
.map(res => res.json());
}
Deprecated approach (Works but deprecated/not usual practice):
Took few hours but found the solution, I created body as a new formdata object, appended parameters to it as key and their values and it worked fine now I am retrieving through $this->input->post.
let body = new FormData;
body.append('userid', Userid);
body.append('taskname', TaskName);
console.log(body);
return this.http.post("http://localhost/ci-abc/api/add_task",body)
.map(res => res.json());
Using these headers in the constructor of my codeigniters API controller
header("Access-Control-Allow-Origin: *");
header('Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Access-Control-Allow-Origin');
header('Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE');
API method:
function add_task_post()
{
$userid = $this->input->post('userid');
$taskname = $this->input->post('taskname');
if (!$taskname || !$userid) {
$this->response("Enter taskname and userid to add", 400);
} else
$result = $this->todo_model->add_task($taskname, $userid);
if ($result === 0) {
$this->response("Task could not be added. Try again.", 404);
} else {
$this->response("success", 200);
}
}

response for preflight is invalid (redirect) error

I am new to Laravel and Lumen framework. I am doing my first project using Lumen. I am trying to create an API calling from angular
Here is my angular code :
app.controller('ListCtrl', ['$scope', '$http', '$location', '$window', function($scope, $http, $location, $window) {
$scope.data = {};
$scope.getdata = function() {
$scope.datas = [];
$headers = {
'Access-Control-Allow-Origin' : '*',
'Access-Control-Allow-Methods' : 'POST, GET, OPTIONS, PUT',
'Content-Type': 'application/json',
'Accept': 'application/json'
};
$http({
url: "http://localhost/service/public/getdata/",
method: "GET",
params: {'place':$scope.data.place,'pincode':$scope.data.pincode},
headers: $headers
})
.success(function(data,status,headers,config) {
$scope.datas=JSON.stringify(data);
console.log($scope.datas);
$scope.navig('/show.html');
})
.error(function(){
alert("failed");
});
};
$scope.navig = function(url) {
$window.location.href = url;
};
}]);
And here is my Lumen route.php :
<?php
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Headers: Content-Type");
$app->get('/', function () use ($app) {
return $app->version();
});
$app->get('getdata','App\Http\Controllers\PlaceController#index');
And here is PlaceController.php
<?php
namespace App\Http\Controllers;
use App\Places;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class PlaceController extends Controller
{
public function __construct()
{
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Headers: Content-Type");
//header("Access-Control-Allow-Origin: http://localhost:8100");
}
public function index()
{
$places = Place::all();
return response()->json($places);
}
}
But it shows "XMLHttpRequest cannot load http://localhost/service/public/getdata/?place=sdfs. Response for preflight is invalid (redirect)" error in console.log.
I have googled for two days,but cant find a solution.
Please help
You might be having problems due to invalid/incorrect Headers in your request. The only type of header that PlaceControllerseems to allow is Content-Type, but you're sending more than that.
Also, Access-Control-Allow-Origin and Access-Control-Allow-Methods headers should be added to the server response for your request, not to the request itself.
From MDN, cross-site requests (which seems to be your case) have to meet the following conditions:
The only allowed methods are:
GET
HEAD
POST
Apart from the headers set automatically by the user agent (e.g. Connection, User-Agent, etc.), the only headers which are allowed to be manually set are:
Accept
Accept-Language
Content-Language
Content-Type
The only allowed values for the Content-Type header are:
application/x-www-form-urlencoded
multipart/form-data
text/plain
Note: I never worked with Laravel or Lumen, but in my case if I don't set the headers correctly I end up with the same response for preflight is invalid (redirect) error.

Categories