I am developing a todo app to work with React and PHP for the first time. I am using Apache(XAMPP).
App.js:
import { useEffect, useState } from "react";
const App = () => {
const [todos, setTodos] = useState([]);
useEffect(() => {
fetch(`${process.env.REACT_APP_ENDPOINT}`, {
method: "POST",
body: JSON.stringify({
action: "todos",
}),
})
.then((response) => response.json())
.then((data) => setTodos(data));
}, []);
return (
<div>
<h1>Todo App</h1>
</div>
);
};
export default App;
index.php:
<?php
header('Access-Control-Allow-Origin: *');
try {
$db = new PDO("mysql:host=localhost;dbname=todo", "mustafa", "12345");
} catch (PDOException $e) {
die($e->getMessage());
}
$action = $_POST['action'];
switch ($action) {
case 'todos':
$query = $db->query("SELECT * FROM todos order by id desc")->fetchAll(PDO::FETCH_ASSOC);
echo json_encode($query);
break;
}
Although I have the header('Access-Control-Allow-Origin: *')
, It throws me the MissingAllowOriginHeader error:
Access to fetch at 'http://localhost/react-php-backend' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
What is the reason that gives this error? How can I fix this? Because of that I cannot connect database.
In 2023, when almost all browsers requires strick origin policy you need to modify your headers, either in .htaccess
<IfModule mod_headers.c>
#Header set Access-Control-Allow-Origin "*"
SetEnvIf Origin "http(s)?://(.+\.)?domain\.ext(:\d{1,5})?$" CORS=$0
Header set Access-Control-Allow-Origin "%{CORS}e" env=CORS
Header merge Vary "Origin"
Header set Access-Control-Allow-Methods "GET, POST, PATCH, PUT, DELETE, OPTIONS"
Header set Access-Control-Allow-Headers: "*"
</IfModule>
or inside php
<?php
function cors()
{
// for options, return imm.
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD']))
// may also be using PUT, PATCH, HEAD etc
{
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);
}
$origin = "*";
if (isset($_REQUEST['origin'])) {
$origin = $_REQUEST['origin'];
}
if (isset($_SERVER['origin'])) {
$origin = $_SERVER['origin'];
}
if (isset($_SERVER['HTTP_REFERER'])) {
$origin = $_SERVER['HTTP_REFERER'];
}
if (isset($_SERVER['HTTP_ORIGIN'])) {
$origin = $_SERVER["HTTP_ORIGIN"];
}
// remove trailing / for origin
$origin = rtrim($origin, "/");
header("Access-Control-Allow-Origin: " . $origin, true);
header("Access-Control-Allow-Headers: *", true);
header('Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS, post, get', true);
header('Access-Control-Allow-Credentials: true', true);
}
cors();
tbh, both would be also ok...