无法访问 api post 方法,始终请求 OPTIONS

Can't access api post method, request always OPTIONS

我正在尝试使用 nuxtjs 作为前端和 slim php 作为后端 api 创建登录表单,当我尝试访问 API 时,我看到了请求方法我发送的是 OPTIONS 而不是 POST,并且在 chrome 开发控制台错误中显示请求被阻止(CORS ). 我知道我必须设置 Access-Control-Allow-Methods 添加 OPTIONS 到它,但仍然失败,在 nuxt js 中设置它的位置(nuxt.config) 或苗条 php?

我尝试从邮递员那里访问 api,它工作正常,我可以看到 Access-Control-Allow-Methods headers 中有 OPTIONS它,但是当我在 vue apps

中尝试时它仍然失败
commons.app.js:434 OPTIONS http://localhost:8080/login 401 (Unauthorized)

Access to XMLHttpRequest at 'http://localhost:8080/login' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

代码来自 slim php (API)

routes.php

// login routes
$app->post('/login', function (Request $request, Response $response, array $args) {

        $input = $request->getParsedBody();
        $sql = "SELECT * FROM groups
                LEFT JOIN users_groups ON groups.groups_id = users_groups.users_groups_id
                LEFT JOIN users ON users_groups.users_groups_id = users.id
                WHERE users.email = :email";
        $sth = $this->db->prepare($sql);
        $sth->bindParam("email", $input['email']);
        $sth->execute();
        $user = $sth->fetchObject();

        // verify email address.
        if (!$user) {
            $container->get('logger')->info("Error trying to login with email : ".$input['email']);
            return $this->response->withJson(['error' => true, 'message' => 'These credentials do not match our records.']);
        }

        // verify password.
        if (!password_verify($input['password'], $user->password)) {
            $container->get('logger')->info("Error trying to login with password : ".$input['password']);
            return $this->response->withJson(['error' => true, 'message' => 'These credentials do not match our records.']);
        }

        // cek apakah sudah login sebelumnya hari ini untuk user ini
        $absensiSql = "SELECT * FROM users_presensi WHERE user_id = :userID";
        $sth = $this->db->prepare($absensiSql);
        $sth->bindParam("userID", $user->id);
        $sth->execute();
        $absensi = $sth->fetchObject();

        // jika belum absen, masukan user ke absensi
        if(!$absensi){
            $status = 1;
            $absensiSql = "INSERT INTO users_presensi(user_id, statuss) VALUES (:userID, :statuss)";
            $sth = $this->db->prepare($absensiSql);
            $sth->bindParam("userID", $user->id);
            $sth->bindParam("statuss", $status);
            $sth->execute();
            // $absensi = $sth->fetchObject();s
        }

        $settings = $this->get('settings'); // get settings array.

        $token = JWT::encode(['id' => $user->id, 'email' => $user->email, 'level' => $user->groups_level], $settings['jwt']['secret'], "HS256");

// i already set the header here
        return $this->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, OPTIONS')
        ->withHeader('Set-Cookie', "token=$token; httpOnly")
        ->withJson(['token' => $token]);

    })->setName('login');

我的 nuxtjs 授权配置 nuxt.config.js

/*
  ** Nuxt.js modules
  */
  modules: [
    '@nuxtjs/vuetify',
    // Doc: https://axios.nuxtjs.org/usage
    '@nuxtjs/axios',
    '@nuxtjs/pwa',
    '@nuxtjs/eslint-module',
    '@nuxtjs/auth'
  ],
  /*
  ** Axios module configuration
  ** See https://axios.nuxtjs.org/options
  */
  axios: {
  },

  /**
   * set auth middleware
   */
  router: {
    middleware: ['auth']
  },
  auth: {
    strategies: {
      local: {
        endpoints: {
          login: { url: 'http://localhost:8080/login', method: 'post', propertyName: 'token' }
        }
        // tokenRequired: true,
        // tokenType: 'bearer'
      }
    }
  }

方法登录来自login.vue

   loginPost: function () {
      this.$auth.loginWith('local', {
        data: {
          username: this.loginData.username,
          password: this.loginData.password
        }
      })
    }

在邮递员中,结果是令牌本身,我认为不应该发生cors错误,但谁知道呢。

我不知道其他浏览器,但我知道 Chrome 不支持在您的 Access-Control-Allow-Origin header 中使用 localhost。你应该做的是在你的开发环境中只告诉它接受所有来源 ->withHeader('Access-Control-Allow-Origin', '*')

OPTIONS 请求是为浏览器发送真正的请求以确定 CORS 规则是什么做准备。