2016-07-26 71 views
1

尽管实现了V3 API我面临以下CORS问题,我Ionic2/Angular2应用:Angular2 Yelp的API CORS错误

的XMLHttpRequest无法加载https://api.yelp.com/v3/businesses/search。对预检请求的响应不会通过访问控制检查:请求的资源上不存在“访问控制 - 允许来源”标头。因此不允许访问原产地'http://localhost:8100'。响应的HTTP状态代码为404.

在使用API​​的V2时,我使用http.jsonp“绕过”CORS问题,因为授权承载应该添加到标头中GET请求(据我所知,Jsonp头不能被修改)。

这就是为什么我试图

private queryYelp(yelpOAuth:YelpCommunication.YelpOAuthSignature, nextTo:AddressLocation.Location):Promise<{}> { 

    let params:URLSearchParams = new URLSearchParams(); 

    params.set('limit', '' + Resources.Constants.Default.YELP.LIMIT); 
    params.set('latitude', '' + nextTo.coordinates[0]); 
    params.set('longitude', '' + nextTo.coordinates[1]); 
    params.set('radius', '' + Resources.Constants.Default.YELP.RADIUS); 
    params.set('sort_by', Resources.Constants.Default.YELP.SORT.BEST_MATCHED); 

    let headers:Headers = new Headers(); 
    headers.append('Authorization', 'Bearer ' + yelpOAuth.access_token); 
    let options:RequestOptions = new RequestOptions({ 
     headers: headers, 
     search: params, 
     withCredentials: true 
    }); 

    return new Promise((resolve, reject) => { 
     this.http.get(Resources.Constants.Default.YELP.URL, options) 
      .map(res => res.json()) 
      .subscribe((businesses:Yelp.YelpBusiness[]) => { 
       resolve(businesses); 
      }, (errorResponse:Response) => { 
       reject(errorResponse); 
      }); 
    }); 
} 

private queryYelp(yelpOAuth:YelpCommunication.YelpOAuthSignature, nextTo:AddressLocation.Location):Promise<{}> { 
    return new Promise((resolve, reject) => { 
     let xhr:XMLHttpRequest = new XMLHttpRequest(); 

     let formData:FormData = new FormData(); 
     formData.append('limit', '' + Resources.Constants.Default.YELP.LIMIT); 
     formData.append('latitude', '' + nextTo.coordinates[0]); 
     formData.append('longitude', '' + nextTo.coordinates[1]); 
     formData.append('radius', '' + Resources.Constants.Default.YELP.RADIUS); 
     formData.append('sort_by', Resources.Constants.Default.YELP.SORT.BEST_MATCHED); 

     xhr.onload =() => { 
      console.log("status " + xhr.status); 
      if (xhr.readyState === XMLHttpRequest.DONE && xhr.status == 201) { 
       let businesses:Yelp.YelpBusiness[] = JSON.parse(xhr.responseText); 
       resolve(businesses); 
      } else { 
       reject(); 
      } 
     }; 

     xhr.onerror =() => { 
      alert('Woops, there was an error making the request.'); 
     }; 

     xhr.open("GET", Resources.Constants.Default.YELP.URL, true); 
     xhr.setRequestHeader("Authorization", 'Bearer ' + yelpOAuth.access_token); 
     xhr.send(formData); 
    }); 
} 

和解决方案都没有成功又名既解决含铅上面列出的CORS错误。

我错过了什么,或者我怎么能从Ionic2/Angular2中查询Yelp API v3?

THX 问候

P.S:请注意,我的OAuth是的access_token不暴露。身份验证由我的后端生成。

UPDATE

@Thierry TEMPLIER答案后,我发现它适用于Ionic2的解决方案。

在浏览器中调试时,我使用代理查询Yelp API V3。为此我加入ionic.config.json文件

"proxies": [{ 
    "path": "/yelp/v3/businesses", 
    "proxyUrl": "https://api.yelp.com/v3/businesses" 
}] 

和不喜欢以下

this.http.get('http://localhost:8100/yelp/v3/businesses/' + 'search', ... 

注意,以下也将工作

this.http.get('/yelp/v3/businesses' + 'search', ... 

当iOS和Android运行查询,该代理不应该使用aka不会工作。为此我做了类似的查询按照我的服务

this.http.get('https://api.yelp.com/v3/businesses/search, ... 

当然,有一些方便,我写了一个大口的任务,让我环境之间进行切换。

但是,此解决方案仅适用于Ionic2。如果我不得不在Angular2的网站中实现它,我需要我也是一个代理,不确定它。为此我在Yelp的API的问题清单打开的副本任务V3

https://github.com/Yelp/yelp-api-v3/issues/21

回答

1

问题不在于以来,浏览器会透明地汉布尔跨域请求的客户端。它会在发送引擎盖下发送Origin标题。服务器必须按如下方式处理CORS:

  • 将CORS头返回到响应中以启用(或不)此类请求。
  • 如有必要,处理预检查的请求。

请参阅本文的详细信息:

我有看的V3版本的文档,可以看到什么关于CORS或JSONP。剩下的唯一解决方案是在服务器应用程序中实施代理作为解决方法。我知道这不是理想的,但它是我看到的唯一可能的解决方案

+0

Thx为您的答案蒂埃里,很高兴知道问题不在我的键盘和我的屏幕之间。我使用离子代理更新了我的帖子,并提供了一些解决方案。我标记你的答案已解决。留言Merci。 –