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:
preflight response issue with ionic3 app on ios build only [ resolved ] and Ionic UIWebView, unfortunately, the request still get the same error...
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:
<?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):
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:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With