Ionic项目中的加拿大邮政费率错误预检的响应包含无效的HTTP状态代码500

Hai*_*ang 5 cors ionic-framework ionic3 angular

我正在处理HTTP请求,该请求将POST请求发送到Canada Post API以查询运输报价:

getRates(weight: number, originPostal, destPostal) {
    const options = {
      headers: new HttpHeaders({
        'Authorization': 'Basic ' + btoa(this.TEST_USERNAME + ':' + this.TEST_PASSWORD),
        'Accept': 'application/vnd.cpc.ship.rate-v3+xml',
        'Content-Type': 'application/vnd.cpc.ship.rate-v3+xml',
        'Accept-language': 'en-CA',
      }),
    };

    const body = `
    <?xml version="1.0" encoding="utf-8"?>
      <mailing-scenario xmlns="http://www.canadapost.ca/ws/ship/rate-v3">
        <customer-number>${this.TEST_NUMBER}</customer-number>
        <parcel-characteristics>
        <weight>${weight}</weight>
        </parcel-characteristics>
        <origin-postal-code>${originPostal}</origin-postal-code>
        <destination>
          <domestic>
            <postal-code>${destPostal}</postal-code>
          </domestic>
        </destination>
      </mailing-scenario>
    `;

    return this.http.post<any>(this.TEST_URL, body, options)
}
Run Code Online (Sandbox Code Playgroud)

查询在Postman上工作正常,而不适用于Ionic项目(ionic serveionic run -l).我在网上搜索它是一个CORS问题Http失败响应(未知网址):0未知错误,我已将下面添加到ionic.config.json文件中

  "proxies": [
    {
      "path": "/price",
      "proxyUrl": "https://ct.soa-gw.canadapost.ca/rs/ship/price"
    }
  ]
Run Code Online (Sandbox Code Playgroud)

API密钥,URL由加拿大邮政提供,可在此处找到

我有错误:

无法加载https://ct.soa-gw.canadapost.ca/rs/ship/price:预检的响应包含无效的HTTP状态代码500.

14:32:24.786 shipping.ts:34 {"headers":{"normalizedNames":{},"lazyUpdate":null,"headers":{}},"status":0,"statusText":"Unknown Error","url":null,"ok":false,"name":"HttpErrorResponse","message":"Http failure response for (unknown url): 0 Unknown Error","error":{"isTrusted":true}}
Run Code Online (Sandbox Code Playgroud)

任何帮助,将不胜感激!

更新于6月15,2018:

我今天在真实设备上试过它,得到这样的错误: 在此输入图像描述

离线应用问题,离子3应用程序只在ios构建[已解决]离子UIWebView,不幸的是,请求仍然得到相同的错误...

Hai*_*ang 3

getRates(weight: number, originPostal, destPostal) {
    this.http.setDataSerializer('utf8');
    return this.http
      .post(
        this.URL,
        this.body(weight, originPostal, destPostal),
        this.headers(this.USER_NAME, this.PASSWORD)
      );
  }

  private headers(username, password) {
    return {
      'Authorization': 'Basic ' + btoa(username + ':' + password),
      'Accept': 'application/vnd.cpc.ship.rate-v3+xml',
      'Content-Type': 'application/vnd.cpc.ship.rate-v3+xml;',
      'Accept-language': 'en-CA'
    };
  }

  private body(weight, originPostal, destPostal) {
    return `<?xml version="1.0" encoding="utf-8"?>
    <mailing-scenario xmlns="http://www.canadapost.ca/ws/ship/rate-v3">
    <customer-number>MY_CUSTOMER_NUMBER</customer-number>
      <parcel-characteristics>
        <weight>${weight}</weight>
      </parcel-characteristics>
      <origin-postal-code>${originPostal}</origin-postal-code>
        <destination>
          <domestic>
            <postal-code>${destPostal}</postal-code>
          </domestic>
        </destination>
    </mailing-scenario>`;
  }
Run Code Online (Sandbox Code Playgroud)

有几个问题会导致请求无法正常工作:

  1. ionic 中的 HttpClient 模块(Angular 模块)总是有 CORS,ionic 团队有相关的 FAQ。就我而言,我使用 firebase 作为后端,因此不经常使用 http,我决定切换到Ionic Native Http
  2. XML问题,标签前有一个前导空格<?xml>,直到打印出错误消息详细信息我才意识到(错误消息本身也是XML格式的,其余的省略,因此一开始我以为它只有错误消息Server,一旦我将整个消息分成几部分并在控制台上打印出来,我发现它是非法的 xml 格式,然后我发现有一个前导空格): 错误

将 XML 转换为 JSON(xml2js 让生活更轻松):

import * as xml2js from 'xml2js';

this.rateProvider.getRates(this.totalWeight, this.ORIGINAL_POSTAL_CODE, this.selectedAddress.postalCode.toUpperCase())
  .then(resp => {
    xml2js.parseString(resp.data, (err, jsonResp) => {
      this.quotes = this.extractQuotes(jsonResp);
      this.presentActionSheet(this.quotes);
      this.isSelected = false;
    });
  })
  .catch(error => {
    console.log(error);
  });
Run Code Online (Sandbox Code Playgroud)

最后,让它发挥作用: 在此输入图像描述