简体   繁体   English

否'Access-Control-Allow-Origin'Symfony 3和React

[英]no 'Access-Control-Allow-Origin' Symfony 3 and React

I am experiencing a major concern. 我遇到了一个重大问题。 I develop an api with symfony 3. This api is queried on Front side with React. 我使用symfony 3开发了一个api。使用React在前端查询此api。 The server used back side (API) is http://127.0.0.1:8000 . 背面(API)使用的服务器是http://127.0.0.1:8000 And the server used on the Front side is http://localhost:3000 . 前端使用的服务器是http:// localhost:3000

When I call the api from the front, I have two errors: - 405 Method Not Allowed - Access to XMLHttpRequest at ' http://127.0.0.1:8000/users/email/settings ' from origin ' http://localhost:3000 ' has been blocked by: CORS policy: Response to preflight check: No 'Access-Control-Allow-Origin' header is present on the requested resource. 当我从前端调用api时,出现两个错误:-不允许405方法-从来源“ http:// localhost ”访问“ http://127.0.0.1:8000/users/email/settings ”处的XMLHttpRequest : 3000 '已被以下方式阻止:CORS策略:对飞行前检查的响应:所请求的资源上不存在“ Access-Control-Allow-Origin”标头。

However, I specified the correct method (patch) and configured the header from the API: 但是,我指定了正确的方法(补丁)并从API配置了标头:

Here is the detailed code: 这是详细的代码:

API (back with symfony) API(返回symfony)

    /**
 * @Route("/users/email/settings", methods={"PATCH"})
 * @param Request $request
 * @param FlashMessage $flashMessage
 */
public function usersEmailEditAction(Request $request, FlashMessage $flashMessage)
{
    if($request->getContent())
    {
        $data = json_decode($request->getContent(), true);

        $em = $this->getDoctrine()->getManager();

        $user = $this->get('security.token_storage')->getToken()->getUser();

        $editUser = $em->getRepository(User::class)->find($user->getId());

        if (!$editUser) {
            return $flashMessage->messageError("USER_NOT_FOUND", 1);
        }

        if (!$data['password']) {
            return $flashMessage->messageError("PASSWORD_NOT_FOUND", 1);
        }

        if (!filter_var($data['email'], FILTER_VALIDATE_EMAIL)) {
            return $flashMessage->messageError("INVALID_EMAIL", 1, "format email invalid");
        }

        if (!filter_var($data['confirmEmail'], FILTER_VALIDATE_EMAIL)) {
            return $flashMessage->messageError("INVALID_EMAIL", 1, "format email invalid");
        }

        if ($data['email'] != $data['confirmEmail']) {
            return $flashMessage->messageError("NO_MATCHING_EMAIL", 1, "les emails sont différents");
        }

        // on vérifie le mot de passe
        $encoder = $this->get('security.password_encoder');

        $isPasswordValid = $encoder->isPasswordValid($user, $data['password']);

        // Le mot de passe n'est pas correct
        if (!$isPasswordValid) { 
            return $flashMessage->messageError("INCORRECT_PASSWORD", 1);
        }

        $editUser->setEmail($data['email']);
        $editUser->setUpdatedAt(new \DateTime());

        $em->flush();

        return $flashMessage->messageSuccess("EMAIL_UPDATED_SUCCESSFULLY", 0);



    }else {
        return $flashMessage->messageWarning("NOTHING_UPDATED", 2);
    }
}

the return $flashMessage 返回$ flashMessage

    public function messageSuccessAction($message, $code, $desc = null)
{
    $response = new Response();
    $response->setContent(json_encode([
        'error' => $code,
        'message' => $message
    ]));

    $response->headers->set('Content-Type', 'application/json');
    $response->headers->set('Access-Control-Allow-Origin', 'http://localhost:3000');
    $response->headers->set('Access-Control-Allow-Methods', 'POST, GET, PUT, DELETE, PATCH, OPTIONS'); 

    return $response;

    //return new JsonResponse(array("error" => $code, "message" => $message));
}

public function messageErrorAction($message, $code, $desc = null)
{
    $response = new Response();
    $response->setContent(json_encode([
        'error' => $code,
        'message' => $message
    ]));

    $response->headers->set('Content-Type', 'application/json');
    $response->headers->set('Access-Control-Allow-Origin', 'http://localhost:3000');
    $response->headers->set('Access-Control-Allow-Methods', 'POST, GET, PUT, DELETE, PATCH, OPTIONS'); 

    return $response;

    //return new JsonResponse(array("error" => $code, "message" => $message));
}

public function messageWarningAction($message, $code, $desc = null)
{

    $response = new Response();
    $response->setContent(json_encode([
        'error' => $code,
        'message' => $message
    ]));

    $response->headers->set('Content-Type', 'application/json');
    $response->headers->set('Access-Control-Allow-Origin', 'http://localhost:3000');
    $response->headers->set('Access-Control-Allow-Methods', 'POST, GET, PUT, DELETE, PATCH, OPTIONS'); 

    return $response;
    //return new JsonResponse(array("error" => $code, "message" => $message));
}

Request API from Front (use Axios) 从前端请求API(使用Axios)

    requestAPI = (myPassword, newEmail, confirmEmail) => {
    axios.patch('http://127.0.0.1:8000/users/email/settings', {
        crossdomain: true,
        password: myPassword,
        email: newEmail,
        confirmEmail: confirmEmail
      })
      .then(function (response) {
        console.log(response);
      })
      .catch(function (error) {
        console.log(error);
      });
}

I also tried without crossdomain, but nothing. 我也尝试了没有跨网域,但一无所获。

Do you have any idea ? 你有什么主意吗 ? Thank you for your helps 谢谢你的帮助

Is the call that gets the 405 Method Not Allowed by any chance an OPTIONS call? OPTIONS调用是否有机会获得405 Method Not Allowed的调用? Also called a "preflight request" . 也称为“预检请求”

For all your CORS needs you should include the NelmioCorsBundle , it is easily configurable and you don't need to set your own CORS headers. 对于您的所有CORS需求,您都应该包括NelmioCorsBundle ,它很容易配置,并且您不需要设置自己的CORS标头。

What happens here is, your browser will check first whether the server understands the CORS protocol with an OPTIONS call. 此处发生的是,您的浏览器将首先检查服务器是否通过OPTIONS调用了解CORS协议。 But that isn't answered by your application, at least not with the correct CORS headers, so your PATCH call is never issued by your browser because of that. 但是您的应用程序并没有回答这一问题,至少没有使用正确的CORS标头,因此您的浏览器从不会发出PATCH调用。 The error message even says so. 错误消息甚至如此。 "Response to preflight check : No 'Access-Control-Allow-Origin' header is present on the requested resource." “对飞行前检查的响应:所请求的资源上没有'Access-Control-Allow-Origin'标头。”

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM