i have set up a following headers in my controller, with the following code
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST');
header("Access-Control-Allow-Headers: X-Requested-With, Content-Type");
how can i achieve this in the zend framework 2,
Thanks
use Zend\Http\Headers;
...
$headers = new Headers();
or
$headers = $httpObject->getHeaders();
then to add headers one by one
$headers->addHeaderLine('Access-Control-Allow-Origin', '*');
$headers->addHeaderLine('Access-Control-Allow-Methods', 'GET, POST');
$headers->addHeaderLine('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type');
or pass all in one array like this
$headers->addHeaders(array(
'Access-Control-Allow-Origin' => '*',
'Access-Control-Allow-Methods' => 'GET, POST',
'Access-Control-Allow-Headers' => 'X-Requested-With, Content-Type'
));
if you created a new headers object
$httpObject->setHeaders($headers);
Related
My angular application runs on http://localhost:4200/ and my Slim4 application runs on localhost:8080. When I try to integrate APIS between angular and slim, GET API works fine, but the POST API does not. I get the below CORS error,
Access to XMLHttpRequest at 'http://localhost:8080/admin/login' from origin 'http://localhost:4200' has been blocked by CORS policy: Request header field cache-control is not allowed by Access-Control-Allow-Headers in preflight response.
My angular request 'content-type' is 'applictaion/json'. Please find the slim4 response header below,
<?php
declare(strict_types=1);
namespace App\Application\ResponseEmitter;
use Psr\Http\Message\ResponseInterface;
use Slim\ResponseEmitter as SlimResponseEmitter;
class ResponseEmitter extends SlimResponseEmitter
{
/**
* {#inheritdoc}
*/
public function emit(ResponseInterface $response): void
{
// This variable should be set to the allowed host from which your API can be accessed with
$origin = isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : '';
$response = $response
->withHeader('Access-Control-Allow-Credentials', 'true')
->withHeader('Access-Control-Allow-Origin', $origin)
->withHeader(
'Access-Control-Allow-Headers',
'X-Requested-With, Content-Type, Accept, Origin, Authorization',
)
->withHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH, DELETE, OPTIONS')
->withHeader('Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0')
->withAddedHeader('Cache-Control', 'post-check=0, pre-check=0')
->withHeader('Pragma', 'no-cache');
if (ob_get_contents()) {
ob_clean();
}
parent::emit($response);
}
}
Have you tried this?
->withHeader('Access-Control-Allow-Origin', '*')
I've tried to set up a Angular App with SLIM Framework v4 Backend; Angular is running local, while Slim is on a Deploy Server. So CORS Setup is needed and I did like given in the documentation:
$app->options('/{routes:.+}', function ($request, $response, $args) {
return $response;
});
$app->add(function ($request, $handler) {
$response = $handler->handle($request);
return $response
->withHeader('Access-Control-Allow-Origin', '*')
->withHeader('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type, Accept, Origin, Authorization')
->withHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, PATCH, OPTIONS');
});
On get Requests the Acces-Control-Allow-Origin Header is present; no problem, everything working as expected. On Put request (example):
$app->put('/event/{id}', function (Request $request, Response $response, $args) use ($app) {
$id = $args['id'];
$response
->withHeader('Access-Control-Allow-Origin', '*')
->withHeader('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type, Accept, Origin, Authorization');
$response->getBody()->write('Test with $id');
return $response;
});
even with an additional add in the function, the header is not present on the response in the browser.
What am I doing wrong?
The request and response object is immutable. You can try this:
$app->put('/event/{id}', function (Request $request, Response $response, $args) {
$id = $args['id'];
$response = $response
->withHeader('Access-Control-Allow-Origin', '*')
->withHeader('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type, Accept, Origin, Authorization');
$response->getBody()->write('Test with $id');
return $response;
}
When I make a POST request I get the error
Access to XMLHttpRequest at 'http://localhost/vla-php/room/create.php' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.
on the console.
Using Postman works fine, however, trying to consume it from a React frontend results in the above error.
I already have CORS enabled by setting access control to allow all origins (*)
.htaccess is an empty file. I doubt if that would be a hinderance.
The PHP code looks like so;
<?php
// required headers
header("Access-Control-Allow-Origin: *");
header("Content-Type: application/json; charset=UTF-8");
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");
// get database connection
include_once '../config/database.php';
// instantiate product object
include_once '../objects/room.php';
$database = new Database();
$db = $database->getConnection();
$room = new Room($db);
// get posted data
$data = json_decode(file_get_contents("php://input"));
// make sure data is not empty
if(
!empty($data->name) &&
!empty($data->category) &&
!empty($data->type)
){
// set product property values
$room->name = $data->name;
$room->category = $data->category;
$room->type = $data->type;
// create the product
if($room->create()){
// set response code - 201 created
http_response_code(201);
// tell the user
echo json_encode(array("message" => "Room was created."));
}
// if unable to create the product, tell the user
else{
// set response code - 503 service unavailable
http_response_code(503);
// tell the user
echo json_encode(array("message" => "Unable to create room."));
}
}
// tell the user data is incomplete
else{
// set response code - 400 bad request
http_response_code(400);
// tell the user
echo json_encode(array("message" => "Unable to create room. Data is incomplete."));
}
?>
Changing the headers to
header('Access-Control-Allow-Origin: *');
header("Access-Control-Allow-Methods: HEAD, GET, POST, PUT, PATCH, DELETE, OPTIONS");
header("Access-Control-Allow-Headers: X-API-KEY, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Request-Method,Access-Control-Request-Headers, Authorization");
header('Content-Type: application/json');
$method = $_SERVER['REQUEST_METHOD'];
if ($method == "OPTIONS") {
header('Access-Control-Allow-Origin: *');
header("Access-Control-Allow-Headers: X-API-KEY, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Request-Method,Access-Control-Request-Headers, Authorization");
header("HTTP/1.1 200 OK");
die();
}
Worked
I am working with CodeIgniter Rest server, I am making PUT request . Everything works fine in the chrome and firefox, but in the internet explorer I keep getting an error saying Request method PUT was not present in the Access-Control-Allow-Methods list., i even added the response headers to allow the different methods , following is the rest service
public function service_put()
{
if (!$this->_allow) return;
$data = $this->_put_args;
if(isset($data))
{
// have my arguments
try{
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST,PUT,GET,DELETE');
header('Access-Control-Allow-Headers: Origin,X-Requested-With,Content-Type, Accept');
$this->response(['done' => TRUE], REST_Controller::HTTP_OK); // (200) HTTP response code
}
catch(Exception $e)
{
$this->response(array('error' => $e->getMessage()), $e->getCode());
}
return;
}
else
{
$this->returnBadRequest();
return;
}
}
I have a issue with my slim app, i want send json responses but with customed headers. My code is like follow:
index.php
require 'vendor/autoload.php';
require 'app/config.php';
require 'app/libs/api.cs.php';
$app = new Slim\App(
[
"settings" => $config,
"apics" => function() { return new APIHelper(); } //This is a class that contain a "helper" for api responses
]
);
require 'app/dependences.php';
require 'app/middleware.php';
require 'app/loader.php';
require 'app/routes.php';
// Run app
$app->run();
app/libs/api.cs.php (The "helper")
<?php
class APIHelper
{
public function sendResponse($response, $status='success' ,$code = 200, $message = "", $data = null)
{
$arrResponse = array();
$arrResponse['status'] = $status;
$arrResponse['code'] = $code;
$arrResponse['message'] = $message;
$arrResponse['data'] = $data;
return $response
->withHeader('Access-Control-Allow-Origin', '*')
->withHeader('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type, Accept, Origin, Authorization, AeroTkn')
->withHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS')
->withHeader('Content-Type','application/json')
->withHeader('X-Powered-By','My API Server')
->withJson($arrResponse,$code);
}
}
my routes file (app/routes.php)
$app->group('/foo', function () {
$this->get('', function ($req, $res, $args) {
return $this->apics->sendResponse($res, 'success' ,200, "Foo API Index By Get", null);
});
$this->post('', function ($req, $res, $args) {
try{
$oBody = $req->getParsedBody();
return $this->apics->sendResponse($res, 'success' ,200, "Foo API POST Response", $oBody);
}
catch(\Exception $ex){
return $this->apics->sendResponse($res, 'error' ,500, "Process Error", array('error' => $ex->getMessage()));
}
});
});
When i trying to run my app with request body, the result is the follow:
Headers:
connection →Keep-Alive
content-type →text/html
date →Wed, 30 Aug 2017 02:22:56 GMT
keep-alive →timeout=2, max=500
server →Apache
transfer-encoding →chunked
Body (returns as simple text and not json encoded)
{"status":"success","code":200,"message":"Foo API POST Response","data":{"one":"1", "two":"2"}}
I've trying put this class as a middleware, but i'm some confused in these subject.
Can you help me telling me if these method is good or where i'm bad.
Thanks to all and i hope for your answers! Nice day
Using Middleware is the ideal answer for your problem
Just add this function in your middeleware file
$app->add(function ($req, $res, $next) {
$response = $next($req, $res);
return $response
->withHeader('Access-Control-Allow-Origin', 'http://mysite')
->withHeader('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type, Accept, Origin, Authorization')
->withHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
->withHeader('Content-Type','application/json');
->withHeader('X-Powered-By','My API Server');
});
I found the "error" was a kindergarden issue hahaha, I've download all my code from the web server for test in my machine, I have the same result, but i found that all my files had strange characters at start, so i re-save the files as utf-8 and the problem is solved. Little details that can create headaches!. Thanks to Nica and Ramy. Ramy: the solution was excellent, now the code are more organizated, i take this practice. Good day to all.