Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Canada Post Rates Error in Ionic Project Response for preflight has invalid HTTP status code 500

I am working on an HTTP request which sends POST request to Canada Post API for querying the quotes of shipping:

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)
}

The query works fine on Postman and not work on the Ionic project(ionic serve and ionic run -l). I searched online and it is a CORS issueHttp failure response for (unknown url): 0 Unknown Error, I have added below into ionic.config.json file

  "proxies": [
    {
      "path": "/price",
      "proxyUrl": "https://ct.soa-gw.canadapost.ca/rs/ship/price"
    }
  ]

The API key, URL are provided by Canada Post which can be found here

Errors I have:

Failed to load https://ct.soa-gw.canadapost.ca/rs/ship/price: Response for preflight has invalid HTTP status code 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}}

Any help would be appreciated!

Update on June 15,2018:

I have tried it on real device today, get such error: enter image description here

preflight response issue with ionic3 app on ios build only [ resolved ] and Ionic UIWebView, unfortunately, the request still get the same error...

like image 599
Haifeng Zhang Avatar asked Oct 16 '22 17:10

Haifeng Zhang


1 Answers

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>`;
  }

There's a couple of issues to make the request not work:

  1. HttpClient module(Angular module) in ionic always have CORS, ionic team has related FAQ. In my case I use firebase as the backend, therefore not use http very often, I decided to switch to Ionic Native Http
  2. XML issue, there's a leading space before tag <?xml> which I didn't realize until print out the error message details(the error message itself was in XML as well, the rest omits, therefore at the beginning I thought it only has error message Server, once I cut the whole message into pieces and print it out on console, I find it was illegal xml format, then I figure out there's a leading space): Error

Convert XML to JSON(xml2js makes life easier):

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);
  });

Finally, get it work: enter image description here

like image 177
Haifeng Zhang Avatar answered Oct 21 '22 08:10

Haifeng Zhang