【问题标题】:Ionic can't get open cors离子无法打开cors
【发布时间】:2019-10-10 21:02:22
【问题描述】:

我正在尝试从 ionic android 应用程序中的实时服务器获取 API 数据,但它返回此错误:

Access to XMLHttpRequest at 'https://example.com/api/categories/' from origin 'http://192.168.43.71:8100' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

服务器设置

现在我将 Laravel 用于实时服务器,它提供的 API 是我在 laravel 应用程序中设置 CORS 的方式:

/bootstrap/app.php

<?php
    header('Access-Control-Allow-Origin: *');
    header('Access-Control-Allow-Methods: GET');
    header('Access-Control-Allow-Headers: *');
    // rest of the file

由于我上面的设置,我在 CORS 测试仪上得到了这个结果

离子设置

所以我一直在阅读如何解决这个问题并且遇到了很多类似的解决方案,这就是我添加到我的 ionic.config.json 文件中的内容

"proxies": [
    {
      "path": "/api/*",
      "proxyUrl": "https://example.com/api/"
    }
  ]

获取请求(离子服务)

这是我请求获取方法的方式

apiUrl = 'https://example.com/api/categories/';
  constructor(private http: HttpClient) { }

  getCategories(): Observable<any> {
    return this.http.get(`${this.apiUrl}`).pipe(
      map(categories => categories)
    );
  }

知道我还应该做些什么来解决这个问题吗?

【问题讨论】:

  • 你应该使用这个github.com/barryvdh/laravel-cors
  • @SalmanZafar 和我在截图中得到的结果一样,不是吗?
  • 但是 cors 问题应该在服务器端处理,这是更好的方法

标签: javascript angular laravel ionic-framework


【解决方案1】:

也许在某些时候,客户端完成了预检 OPTIONS 请求,并且由于它不是您的 Access-Control-Allow-Methods 中列出的方法,因此最终会导致 CORS 问题。

您应该尝试使用 OPTIONS 方法向您的服务器端点发出请求以检查是否是这种情况,您可以使用 POSTMAN 进行此测试。

然后尝试将OPTIONS方法添加到Access-Control-Allow-Methods并检查差异。

【讨论】:

  • 在邮递员中它返回数据很好,没有设置任何标题,我也将我的方法从 get 更改为 *
  • 是的,因为邮递员不是浏览器,您可以尝试将 OPTIONS 添加到您的 Access-Control-Allow-Methods 中,看看您的应用是否有任何差异
  • 我做了很遗憾没有区别
【解决方案2】:

我为我的 API 使用这些标头解决了我的问题:

header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Credentials: true ");
header("Access-Control-Allow-Methods:GET,POST");
header("Access-Control-Allow-Headers: Authorization, Content-Type, Depth, User-Agent, X-File-Size, X-Requested-With, If-Modified-Since, X-File-Name, Cache-Control");

还有 Angular 的 Http:

//GET data details
 getData(authToken){
      const httpOptions = {
          headers: new HttpHeaders({
              'Accept': 'application/json, text/plain',
              'Content-Type':  'application/json',
              'Authorization': authToken
            })
   };
   //console.log(authToken);
   return this.http.get(this.apiGetUrl, httpOptions).retry(3);
 }
与前面的答案一样,选项请求会自动通过 GET 或 POST 发送。如果你有 apache 服务器,你可以 echo$headers = apache_request_headers(); 看看发生了什么。 $_SERVER and Apachehere 的比较。

就我而言,我运行 if 语句:

if(isset($headers["Authorization"]) && isset($headers["Content-Type"])){
  //handle get request
  }
else{
  //handle options request
   echo " False,Re-routing Options Request";
  }

我会在浏览器中测试您的 HTTP 调用并查看开发工具以确认正在发送的请求。我希望这会有所帮助!

【讨论】:

  • 谢谢你,我赞成你的回答,因为我需要它的一部分,但它不是完整的解决方案,所以我要自己分享。
【解决方案3】:

已解决

感谢Stephen Romero 指出此解决方案的重要部分,

根据斯蒂芬的回答,我将此代码添加到我的函数中:

const httpOptions = {
      headers: new HttpHeaders({
        'Accept': 'application/json, text/plain',
        'Content-Type': 'application/json'
      })
    };

并在我的获取请求中使用它,例如:

return this.http.get(`${this.apiUrl}`, httpOptions).pipe(

现在我在我的 laravel 应用程序上使用(安装)this package 的 for 标头权限并将配置文件设置为以下代码:

return [
    /*
    |--------------------------------------------------------------------------
    | Laravel CORS
    |--------------------------------------------------------------------------
    |
    | allowedOrigins, allowedHeaders and allowedMethods can be set to array('*')
    | to accept any value.
    |
    */

    'supportsCredentials' => false,
    'allowedOrigins' => ['*'],
    'allowedOriginsPatterns' => [],
    'allowedHeaders' => ['*'],
    'allowedMethods' => ['GET', 'OPTIONS'],
    'exposedHeaders' => [],
    'maxAge' => 0,

];

对于那些不使用 Laravel 的人

这样设置你的标题:

if($request_method = 'GET'){
    header('Access-Control-Allow-Origin: *');
    header('Access-Control-Allow-Methods: GET, OPTIONS');
    header('Access-Control-Allow-Headers: Authorization, Expires, Pragma, DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range');
    header("Access-Control-Expose-Headers: *");
}

这个头文件最重要的部分是Access-Control-Allow-Headers 部分,如果你只是使用* 它是行不通的!您需要设置标题名称。

希望对你有帮助。

更新

忘记提及,为了避免错误301,您需要从您的 api url 末尾删除 /

// my api (before)
https://example.com/api/categories/

//changed to
https://example.com/api/categories

【讨论】:

    猜你喜欢
    • 2019-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-16
    • 1970-01-01
    • 2019-05-29
    • 2018-07-10
    • 1970-01-01
    相关资源
    最近更新 更多