I get an error when I try to retrieve a list of objects from a link (php server).
Blocking of a multi-origin request (cross-origin request): the "same
source" policy does not allow access to the remote resource located at
http: //localhost/eReport/index.php. Reason:
"Access-control-authorization-origin" token missing in the CORS
"Access-Control-Allow-Headers" CORS header.
I added a header like this tuto that is recommended on this link but I still have this error.
Can you help me please ?
My Service page:
#Injectable()
export class ReportService{
private baseUrl: string = 'http://localhost/report/reports.php';
constructor(private http : Http){}
getAll(): Observable<Report[]>{
let report$ = this.http
.get(`${this.baseUrl}`, { headers: this.getHeaders()})
.map(mapReports);
return report$;
}
private getHeaders(){
// I included these headers because otherwise FireFox
// will request text/html
let headers = new Headers();
headers.append('Accept', 'application/json');
headers.append('Content-Type', 'application/x-www-form-urlencoded;charset=UTF-8');
return headers;
}
get(id: number): Observable<Report> {
let report$ = this.http
.get(`${this.baseUrl}/report/${id}`, {headers: this.getHeaders()})
.map(mapReport);
return report$;
}
My php page
header("Access-Control-Allow-Origin: *");
$tab = array(
array('id'=> '12', 'name'=> 'test','description' => '2018-04-01','url'=>'../../../assets/img/chat1.png' ),
array('id'=> '13', 'name'=> 'test','description' => '2018-04-01','url'=>'../../../assets/img/highcharts.png' )
);
echo json_encode($tab);
?>
Perhaps the quickest fix is to change your base url in the Angular app to /report/reports.php if the requests are going to the same server that served the app.
Your request is not working because when the client sends content of type application/json, the browser doesn't send the request right away. If you restart your browser then observe the network tab you will notice that instead of your GET, an OPTIONS request is first send, that includes headers similar to these:
Origin: yourserver
Access-Control-Request-Method: GET
Access-Control-Request-Headers: Content-Type, Accept
In this scenario, the browser expects the server to return not just the Access-Control-Allow-Origin header (which you're already doing), but all of these:
Access-Control-Allow-Origin: yourserver (or *)
Access-Control-Allow-Methods: GET (or a list eg: GET, POST, OPTIONS)
Access-Control-Allow-Headers: Content-Type, Accept (the same headers from above)
So you need to read the request headers from the previous block, and use their values when setting the response headers. If you have the apache_request_headers() method it's pretty easy. You can also get them from the $_SERVER superglobal.
// set required headers:
header("Access-Control-Allow-Origin: $_SERVER[HTTP_ORIGIN]");
header("Access-Control-Allow-Methods: $_SERVER[HTTP_ACCESS_CONTROL_REQUEST_METHOD]");
header("Access-Control-Allow-Headers: $_SERVER[HTTP_ACCESS_CONTROL_REQUEST_HEADERS]");
See this helpful article
Related
I try to fetch a route from candriam-app.nanosite.tech to candriam.nanosite.tech, I have tried several methods to allow headers but I still have this error
Access to fetch at 'https://xxxA/wp-json/nf-submissions/v1/form/1' from origin 'https://xxxB' has been blocked by CORS policy: Request header field nf-rest-key is not allowed by Access-Control-Allow-Headers in preflight response.
I want to create a headless Wordpress of the website xxxA. I can perform request on the WP Rest API without any problem from candriam-app.nanosite.tech, but I have issues with an endpoint created by this extension : https://github.com/haet/ninja-forms-submissions-rest-endpoint
I followed the documentation and my code to perform the request is like this :
export async function getApiContactForm(route, params = { method: 'get' }) {
const data = await fetch(route, {
method: params.method,
headers: {
'Content-Type': 'application/json',
'NF-REST-Key': 'xxxxxxxxxxx',
},
})
const body = data.json()
return body
}
The NF-Rest-Key is of course the same given by the module.
I have tried different methods on the server-side :
In functions.php, I tried this code :
header( 'Access-Control-Allow-Origin: * ' );
header( 'Access-Control-Allow-Methods: GET' );
header( 'Access-Control-Allow-Credentials: true' );
header( 'Access-Control-Allow-Headers: nf-rest-key' );
In .htaccess file of xxxxxA, I tried this code :
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "*"
</IfModule>
I aso tried :
Header set Access-Control-Allow-Origin *
Header set AMP-Access-Control-Allow-Source-Origin *
But I still get the error.
Is it possible that the plugin is bugged ? Do I have to specifically allow this plugin, this header (nf-rest-key) from the server ?
When I check the headers of the server (like here : https://securityheaders.com/) am I supposed to see that the website where my app is stored is authorised ?
I resolved my problem by adding this code to functions.php :
add_action('init', 'handle_preflight');
function handle_preflight()
{
$origin = get_http_origin();
if ($origin == 'http://localhost:8080' || $origin == 'https://xxxxxB') {
// You can set more specific domains if you need
header("Access-Control-Allow-Origin: " . $origin);
header("Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE");
header("Access-Control-Allow-Credentials: true");
header('Access-Control-Allow-Headers: NF-REST-Key, Content-Type');
if ('OPTIONS' == $_SERVER['REQUEST_METHOD']) {
status_header(200);
exit();
}
}
}
So I've been trying to pass data from my front-end to my back-end (however, I'm not very experienced within this area). The data comes through, however, if I try to insert the data into my MySQL-DB through PDO the browser gives me the following error:
Failed to load http://localhost:8888/post_recipe.php: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled."
JS
postToAPI = () => {
fetch(`http://localhost:8888/post_recipe.php`, {
method: 'POST',
headers: {
'Content-Type': 'text/html'
},
mode: 'cors',
body: JSON.stringify({
title: this.state.title,
description: this.state.description,
userID: this.props.userInfo.response.id,
name: this.props.userInfo.response.name,
stepByStep: (this.state.stepByStep),
recipeIngredients: (this.state.recipeIngredients),
profileImg: this.props.userInfo.response.picture.data.url
})
})
.then((response) => response.json())
.then((fetch) => {
console.log(fetch)
});
}
PHP
<?php
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Credentials: true');
header("Content-type: text/html; charset=utf-8");
header('Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE, OPTIONS');
header('Access-Control-Allow-Headers: Origin, Content-Type, X-Auth-Token');
$post = json_decode(file_get_contents('php://input'));
$array = json_decode(json_encode($post), True);
$pdo = new PDO(
"mysql:host=localhost:8889;dbname=veganify;charset=utf8",
"root",
"root"
);
$statement = $pdo->prepare(
"INSERT INTO posts (title, description, userID, name, stepByStep, recipeIngredients, profileImg)
VALUES (:title, :description, :userID, :name, :stepByStep, :recipeIngredients, :profileImg)"
);
$statement->execute(array(
":title" => $array["title"],
":description" => $array["description"],
":userID" => $array["userID"],
":name" => $array["name"],
":stepByStep" => $array["stepByStep"],
":recipeIngredients" => $array["recipeIngredients"],
":profileImg" => $array["profileImg"]
));
}
echo json_encode($array);
?>
So if I delete the MySQL-insertion, the data comes back to the front-end. I have been stuck here for a while now searching various forums for a solution. The error message says that the header is not present, however it is there, as you can see.
Any help would be much appreciated!
Cheers!
Good afternoon, this is because of the apache blocking requests from different sources ie if your backend is at http://yourdomain.com/client and your font-end is at localhost:3001 will cause a because they are of different (host) origins.
To solve:
Use the .htaccess file in your api / backend folder, for example, in my application my index.php is not in localhost / my-api / public directory then my .htaccess file in this directory directory localhost / my-api / public
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Origin: "*" (allow access from any origin)
Header set Access-Control-Allow-Origin: "http://motech-ui.example" (allow access from only "http://motech-ui.example" origin)
Access-Control-Allow-Origin: "http://motech-ui.example | http://other.domain" (allow access from two mentioned origins)
</IfModule>
Or config in apache.conf
Access-Control-Allow-Origin: "*" (allow access from any origin)
Access-Control-Allow-Origin: "http://motech-ui.example" (allow access from only "http://motech-ui.example" origin)
Access-Control-Allow-Origin: "http://motech-ui.example | http://other.domain" (allow access from two mentioned origins)
CORS in Javascript and PHP works like.
OPTIONS method request will be triggered from browser side.
Server side (PHP) should accept the OPTIONS request, by responding 'OK'.
Now a proper POST request will be triggered from browser side, which will go to your functionality location where your PHP code will gets executed.
if ($_SERVER["REQUEST_METHOD"] === "OPTIONS") {
//location where you can handle your request and respond ok
echo 'OK';
}
If you can not control the sever side, you can work around like me on
Client side only.
If you can control server side, you can use server side solution. I am not discus it here.
Only on client side, work around is
use dataType: 'jsonp',
async function get_ajax_data(){
var _reprojected_lat_lng = await $.ajax({
type: 'GET',
dataType: 'jsonp',
data: {},
url: _reprojection_url,
error: function (jqXHR, textStatus, errorThrown) {
console.log(jqXHR)
},
success: function (data) {
console.log(data);
// note: data is already json type, you just specify dataType: jsonp
return data;
}
});
} // function
I am making simple application with React that sends ajax requests to API made with Symfony. I am developing both the react app and symfony api. I am sending request from localhost:3000 to localhost:8000. Here is the ajax request that I am sending
addUser (data) {
console.log('made it')
let request = {
method: 'post',
url: 'http://127.0.0.1:8000/user/post',
data: JSON.stringify({'username': data}),
contentType: 'application/json'
}
$.ajax(request)
.done(data => this.addUserSuccess(data))
.fail(err => this.addUserFail(err))
}
and here is the Symmfony app that takes care of the request
/**
* Creates a new user entity.
*
* #Route("/post", name="user_new")
* #Method({"GET", "POST"})
*/
function newAction(Request $request ) {
echo $request;
$body = $request->getContent();
$body = json_decode($body,true);
$username = $body['username'];
$user = new User($username);
$em = $this->getDoctrine()->getManager();
$em->persist($user);
$em->flush();
return new JsonResponse($user,200,array('Access-Control-Allow-Origin'=> '*'));
}
I am so far in the beginning and as you can see I am creating new user without password, security or anything. I just want to make it work and be able to send request from the app to the api. Here is the result
XMLHttpRequest cannot load http://127.0.0.1:8000/user/post. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. The response had HTTP status code 405.
I have seen many questions like this one before and one of the answers was to return JsonResponse with the header and as you can see it does not work.
Here is one of the quenstions whose answer I followed - Origin is not allowed by Access-Control-Allow-Origin but unfortunately with no success.
Can you tell me how to fix it? Thank you in advance!
Here's what I'm doing for the same situation. In app/config/config_dev.yml, add a new service. Putting this in config_dev.yml means this will only affect requests through app_dev.php.
services:
app.cors_listener:
class: AppBundle\Security\CorsListener
tags:
- { name: kernel.event_listener, event: kernel.response, method: onKernelResponse }
And the contents of AppBundle/Security/CorsListener.php:
<?php
namespace AppBundle\Security;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
// Based on http://stackoverflow.com/a/21720357
class CorsListener
{
public function onKernelResponse(FilterResponseEvent $event)
{
$responseHeaders = $event->getResponse()->headers;
$responseHeaders->set('Access-Control-Allow-Headers', 'origin, content-type, accept, credentials');
$responseHeaders->set('Access-Control-Allow-Origin', 'http://localhost:8080');
$responseHeaders->set('Access-Control-Allow-Credentials', 'true');
$responseHeaders->set('Access-Control-Allow-Methods', 'POST, GET, PUT, DELETE, PATCH, OPTIONS');
}
}
You need to set the correct headers on your PHP file.
header('Access-Control-Allow-Origin: *');
I have application where I getting code from stash raw file. Scrapping from public repositories is simple, it looks like this:
public getRawFile(rawLink: string) {
return this.http.get(rawLink).map((res: Response) => res.text());
}
But now I would like to get code from stash raw file, but from private repository. If user have access(is logged into stash) than source code from raw file is loaded.
If I trying same way, I getting respone:
XMLHttpRequest cannot load 'private_stash_file_link'. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost' is therefore not allowed access.
EXCEPTION: Response with status: 0 for URL: null
Uncaught Response with status: 0 for URL: null
How can I handle this, cookies, specific options for get request, is it even possible?
EDIT 1.
Tried:
public getRawFile(link: string) {
let headers = new Headers();
headers.append('Access-Control-Allow-Headers', 'Content-Type');
headers.append('Access-Control-Allow-Methods', 'GET, OPTIONS');
headers.append('Access-Control-Allow-Origin', '*');
let options = new RequestOptions({headers: headers, withCredentials: true});
return this.http.get(link, options).map((res: Response) => res.text());
}
but same result for private repository..
plunker
The server that you are making the request to has to implement CORS to grant JavaScript from your website access (Cross Origin Resource Sharing (CORS)). So if you have access to the place where you are scraping, then add the following HTTP headers at the response of the receiving end:
Access-Control-Allow-Headers: Content-Type
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Origin: *.example.com
Make sure to replace "*.example.com" with the domain name of the host that is sending the data/getting the data. Doing this should fix your problem.
I'm developing a REST-ful application using Yii framework for the server side and Angular JS for the client side
I'm using the restfulyii extension to generate the api
:And I'm facing a problem when I'm sending a PUT request.
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at ..... This can be fixed by moving the resource to the same domain or enabling CORS.
But it's working for post + get requests
I saw different solutions but none of them worked.
I tried to put those is server side
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS");
header("Access-Control-Allow-Headers: x-requested-with, Content-Type, origin, authorization, accept, client-security-token");
header("Access-Control-Max-Age: 1000");
and tried to put this code in the angular js module:
$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];
and also I tried to put
$http.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded";
The request converted into OPTIONS request
and the response from the server became as following:
Access-Control-Allow-Headers:x-requested-with, Content-Type, origin, authorization, accept, client-security-token
Access-Control-Allow-Methods:GET, POST, PUT, DELETE, OPTIONS Access-Control-Allow-
Origin:http://localhost:8383
Access-Control-Max-Age:1000
Connection:close
Content-Type:text/html Date:Fri, 24 Oct 2014 06:49:32 GMT
Server:Apache/2.4.7 (Win32) OpenSSL/1.0.1e PHP/5.5.9 X-Powered-By:PHP/5.5.9
I have a base controller for all my rest controllers that use restangular which has the following events.
public function restEvents()
{
$this->onRest('req.cors.access.control.allow.origin', function() {
return ['*']; //List of sites allowed to make CORS requests
});
$this->onRest('req.cors.access.control.allow.methods', function() {
return ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS']; //List of allowed http methods (verbs)
});
$this->onRest('req.auth.cors', function ($allowed_origins) {
if (in_array('*', $allowed_origins)) {
return true;
}
if((isset($_SERVER['HTTP_ORIGIN'])) && (( array_search($_SERVER['HTTP_ORIGIN'], $allowed_origins)) !== false )) {
return true;
}
return false;
});
$this->onRest('req.cors.access.control.allow.headers', function($application_id) {
return ["X_{$application_id}_CORS", "Content-Type", "Authorization", "X_REST_REQUEST"];
});
}
Client side I am using restangular with the following options:
RestangularProvider.setDefaultHttpFields({withCredentials: true});
RestangularProvider.setDefaultHeaders({X_REST_CORS: 'Yes'});
RestangularProvider.setDefaultHttpFields({cache: false});
I hope this helps....