REACT + PHP - 仅在 POST 请求中阻止我的 CORS 策略

abl*_*cz1 3 javascript php reactjs fetch-api

概述
我的React 应用程序托管在github-pages上,PHP API托管在标准付费托管上。

这有效(GET)
当我开始开发我的应用程序时,我遇到了一个非常流行的错误,即Access to fetch at ... has been blocked by CORS policy. 我找到了一个快速修复方法,将其写header("Access-Control-Allow-Origin: *")在 PHP 的第一行中,并且它有效。然而这些是GET 请求

这不起作用(POST)
这次我有一段代码,我必须在其中使用POST请求并需要访问它的响应。这是负责发送 post 请求的代码段:

const editEvent = async () => {
    const requestOptions = {
        method: 'POST',
        headers: { 'Content-Type': 'application/json', },
        body: JSON.stringify({ eventID: chosenEvent, courseID: courseID, groupID: groupID, time:time, date: date, description: description, typeID: typeID, password: password}),
        mode: 'cors',
    };
    const response = await fetch(`https://aleksanderblaszkiewicz.pl/kiedykolos/edit_event.php`, requestOptions);
}
Run Code Online (Sandbox Code Playgroud)

它又发生了 - 我遇到了同样的错误Access to fetch at ... has been blocked by CORS policy。我现在使用的解决方案是使用mode: 'no cors',但它不允许我得到响应,因为它是不透明的。我发现的另一个解决方案是添加更多标头:

header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE, OPTIONS");
header("Access-Control-Allow-Headers: Content-Type, Accept, Authorization, X-Requested-With, X-Auth-Token, Origin, Application");
Run Code Online (Sandbox Code Playgroud)

但效果不太好。有什么建议么?完整错误代码:

从源“http://localhost:3000”获取“https://aleksanderblaszkiewicz.pl/kiedykolos/add_event.php”的访问已被 CORS 策略阻止:对预检请求的响应未通过访问控制检查:否请求的资源上存在“Access-Control-Allow-Origin”标头。如果不透明响应满足您的需求,请将请求模式设置为“no-cors”以在禁用 CORS 的情况下获取资源。

完整的 PHP 代码:

const editEvent = async () => {
    const requestOptions = {
        method: 'POST',
        headers: { 'Content-Type': 'application/json', },
        body: JSON.stringify({ eventID: chosenEvent, courseID: courseID, groupID: groupID, time:time, date: date, description: description, typeID: typeID, password: password}),
        mode: 'cors',
    };
    const response = await fetch(`https://aleksanderblaszkiewicz.pl/kiedykolos/edit_event.php`, requestOptions);
}
Run Code Online (Sandbox Code Playgroud)

rag*_*hes 6

问题在于您的服务器设置了许多不属于原始请求一部分的允许标头。Fetch 对象中唯一的请求标头是content-type: application/json,因此必须与服务器中的 Access-Control-Allow-Headers 匹配。

Access-Control-Request-Headers 标头在发出预检请求时使用,让服务器知道发出实际请求时将使用哪些 HTTP 标头(例如使用 setRequestHeader())。此浏览器端标头将由 Access-Control-Allow-Headers 的互补服务器端标头进行响应。

来源 Mozilla

这是一个潜在的解决方案,可以让您的 CORS 请求发挥作用:

  // In your code, this function is never called...
  const editEvent = async () => {
        const requestOptions = {
            method: 'POST',
            headers: { 'Content-Type': 'application/json', },
            body: JSON.stringify({ eventID: chosenEvent, courseID: courseID, groupID: groupID, time:time, date: date, description: description, typeID: typeID, password: password}),
        };
        await fetch(`https://aleksanderblaszkiewicz.pl/kiedykolos/edit_event.php`, requestOptions)
          .then(response => console.log(JSON.stringify(response)))
          .catch(error => console.log(error))


    }
Run Code Online (Sandbox Code Playgroud)

这是一个飞行前请求,因为内容类型是 application/json。这意味着浏览器向服务器发出“预请求”,看看该请求是否可以执行(并发送响应)。

因此,在服务器端代码中,您只能使用:

   header("Access-Control-Allow-Origin: http://localhost:3000");
Run Code Online (Sandbox Code Playgroud)

或者:

   header("Access-Control-Allow-Origin: *");
Run Code Online (Sandbox Code Playgroud)

如果您想在 Access-Control-Allow-Origin 旁边包含另一个响应标头,请仅允许该content-type标头,即您在源 Fetch 请求中设置的标头:

   header("Access-Control-Allow-Headers: Content-Type");
Run Code Online (Sandbox Code Playgroud)