Can't get POST call to work

All,

I’m struggling to get a POST call to work in code that I see working fine within a pre-existing web-app when I watch it through Google Developer tools.

When it runs (successfully), here’s what Chrome shows:

Request URL:https://mobile-qa.company.org/webapp/j_security_check
Request Method:POST
Status Code:200 OK
Remote Address:111.122.133.144:443
Referrer Policy:no-referrer-when-downgrade

Response Headers
HTTP/1.1 200 OK
Connection: Keep-Alive
Transfer-Encoding: chunked
Date: Tue, 02 May 2017 13:49:46 GMT
Content-Type: application/json;charset=ISO-8859-1
X-Powered-By: Servlet/3.0
Content-Language: en-US
Set-Cookie: mobileqa-company-org=!m/iZ0sSPpGG3Jmp2DJyE0svLRgPuVcvRKHztygHzboRPzl940wdc0hmEsZ7SawL8cK6IgF7qVyyArw==; expires=Tue, 02-May-2017 15:06:50 GMT; path=/
Set-Cookie: TS016c732b=01d6e853696d624aef04ae664398f6375ed935f2fa3f05cb5cc5d7a1fcce6e1cb1e8f8c860a98abbb2da9ba6c86c65a573f9ad545429017870c97ca0787634d7c03d54b977; Path=/
Set-Cookie: TS016c732b_30=019990d1416c15a8630b7119355802c350569e1e832934320401ebc1beb82846cdc04dbd1571d94b7ccc05a0565f2ac4729f1f4f20; Path=/

Request Headers
POST /webapp/j_security_check HTTP/1.1
Host: mobile-qa.company.org
Connection: keep-alive
Content-Length: 77
Accept: application/json, text/javascript, /; q=0.01
Origin: https://mobile-qa.company.org
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Referer: https://mobile-qa.company.org/www/public/index.html
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.8
Cookie: TLTUID=1B5CC36B48DA87910EBD9C9B5A4153D6; _qca=P0-279986168-1491423610241; AMCV4B46D70754F9EFCB0A4C98C6%40AdobeOrg=793872103%7CMCIDTS%7C17262%7CMCMID%7C80349030032986718604014573759743869002%7CMCAAMLH-1492028410%7C7%7CMCAAMB-1492028410%7CNRX38WO0n5BH8Th-nqAG_A%7CMCAID%7CNONE; _utma=42480164.1486989436.1491423610.1491427249.1491491494.3; __utmz=42480164.1491423610.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); JSESSIONID=0000wFVIw14uRV2oTyJpC4AkTgp:1849ra9bd; TS016c732b30=019990d14105e264ece505004957bc5a19d74893682934320401ebc1beb82846cdc04dbd15de580d7fa980a374ea33dae64d4f2a1c; mobileqa-company-org=!v2KE7TJCG/my5Yt2DJyE0svLRgPuVWY8HUMpsCHAjfqi29zST8q75zlOEQHLtA+bpPkcQ8kp3/Ru+g==; TS016c732b=01d6e8536908af27366aeadb472d78c3f8844e74703f05cb5cc5d7a1fcce6e1cb1e8f8c860af8e45dbea4ee7d5bd0400ec2b1319eacfcc5a9a870366ebf680d4e5664c6a66

Form Data
j_username=xxxxx&j_password=yyyy&hash=null&clientVersion=2.7&buildNumber=6183

And this is the code I’m using (which receives a 500 error from the server):

import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
import {Http, RequestOptions} from '@angular/http';
import {Headers} from '@angular/http';

@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {

	public resultJson: any;
	public serviceCallEndPoint: any;

  constructor(public navCtrl: NavController, public http: Http) {
    this.serviceCallEndPoint = 'https://www.reddit.com/r/gifs/new/.json?limit=10';

  }

  callSvc()
  {
    this.resultJson = "";

    var headers = new Headers();
    headers.append("Accept", 'application/json');
    headers.append('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
    let options = new RequestOptions({ headers: headers });


    let postBody = {
      j_username:'61190',
      j_password:'YYYYY',
      hash:null,
      clientVersion:'2.7',
      buildNumber:'6183'
    }

    //HTTP.useBasicAuth('61190', 'abcd');

      this.http.post('https://mobile-qa.company.org/webapp/j_security_check', postBody, options).subscribe(
      data => {
        this.resultJson = data.text();
      },
      err => {
        console.log("Communication Error - Please verify connection and try again")
      }
    );
  }
}

Can somebody point me in the right direction here?

Thanks!

Jai

So how does the code you are running look in Chrome on ionic serve?

PS: Please use the </> button above the post input field to format your code or error message or wrap it in ``` (“code fences”) manually. This will make sure your text is readable and if it recognizes the programming language it also automatically adds code syntax highlighting. Thanks.

Sujan12,

Thanks for the info - I’ll post code correctly from now on!

In answer to your question, here’s the Chrome results to the call:

Request URL:https://mobile-qa.company.org/webapp/j_security_check
Request Method:POST
Status Code:500 Internal Server Error
Remote Address:111.122.133.144:443
Referrer Policy:no-referrer-when-downgrade

Response Headers
HTTP/1.1 500 Internal Server Error
Connection: Keep-Alive
Content-Length: 0
Date: Tue, 02 May 2017 15:51:09 GMT
X-Powered-By: Servlet/3.0
Content-Language: en-US
Set-Cookie: mobileqa-company-org=!6ElbTHFstgihHeZ2DJyE0svLRgPuVY4jF6r5rLYWSYBYHNrJNBC6uObuFrcAOBHeaWBfwAUcfGAWJA==; expires=Tue, 02-May-2017 16:26:24 GMT; path=/
Set-Cookie: TS016c732b=01d6e853691db98dc34aef542f40d2c84d05d3c83fc12779f788499f6b7b0283ba70e849d89aac725d68172e6002f9572c6dd9f92d; Path=/
Set-Cookie: TS016c732b_30=019990d141cc1f80e3e2365c2176f73debd2e0f0878452994491708908c15e445917fe19f3df325181effa42b9705838cad1852fcb; Path=/

Request Headers
POST /webapp/j_security_check HTTP/1.1
Host: mobile-qa.company.org
Connection: keep-alive
Content-Length: 77
Accept: application/json
Origin: http://localhost:8100
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Referer: http://localhost:8100/
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.8

Form Data
j_username=xxxxx&j_password=yyyy&hash=null&clientVersion=2.7&buildNumber=6183

Thanks.

Now it’s eay to see the difference in requets:

vs.[quote=“Jaidex, post:3, topic:88615”]
Form Data
{
“j_username”: “61190”,
“j_password”: “YYYYY”,
“hash”: null,
“clientVersion”: “2.7”,
“buildNumber”: “6183”
}
[/quote]

Your Ionic code is submitting the form data as a JSON array and not as the expected query string.

Sorry, my bad. I just showed them differently when copied them from Chrome. I’ve updated the initial post to show the code the same way (as a string).

Nonetheless, I changed it to use a string just to try it and it gave exactly the same error.

Any other thoughts? I do see that the working code has this:

Transfer-Encoding: chunked

and mine doesn’t, so I’m going to try that, but I’m not hopeful!

Jai

So here is what I see when I look at the both request/responses you posted:

  1. One is for an IP in China, the other for a IP in US.
  2. Origin and Referer are not identical - an application could check for those and 500 a request if not as expected
  3. The second, 500 request doesn’t submit a Cookie as the other one does

If I were you I would recreate the first request in an REST client like Postman or Insomnia and then remove stuff or change stuff to the things your Ionic app sends until it breaks. Then you know what causes it to break.

(Or if you have access to the server: Find out what is going on by finding out what causes the 500)

Sujan12,

The ip addresses are faked - I just used those to hide my company ip.

As far as PostMan, it runs just fine, but I can’t figure out how to translate that into a successful call within my Ionic code.

Jai

You posted two different calls. I would create the first one and then slowly transform this one to the second one you posted in Postman. Origin, Referer, Cookie, Transfer-Encoding are all stuff one can change and test the call again to see when it breaks.

The only difference I see (which I also see in the Chrome Developer Tools output) is that a cookie is being set for the call. I don’t know what that cookie is or how to code for it. Other than that, I don’t see any differences.

Note that I did ask in another post if anybody knew how of a tutorial that showed how to convert a PostMan call into Ionic code, but I haven’t received any responses.

Just remove the Cookie from the Postman request you have and see if it breaks it. If it does, your Ionic code obviously needs this parameter, too. If not, this is not a problem.

Postman is doing some stuff for you relating cross domain request. Are you sure it isn’t some kind of CORS issue?

I’m PRETTY sure of it (but not positive, since I’ve never been successful). I was originally getting a preflight response (CORS) error, but I added “Moesif Origin & CORS Changer” to Chrome and that error went away. Since then, I’ve been getting this 500 error with not explanation since.

Well then you possibly are trying to circumvent CORS on the server you’re trying to post to, which may lead to this error. Probably if you turn off this plugin, you will see an (failing) options call. If you know the owner or are the owner of the server, you should manage the CORS settings over there. But off course i’m not entirely sure whether is the CORS that’s causing your internal server error in the end or not.

Could you please check if the post is failing on the options call with a CORS error when turning off this plugin?

Okay, I’ve tried different code to the the post. Now I’m getting:


(index):1 XMLHttpRequest cannot load https://mobile-qa.company.org/webapp/j_security_check. Response for preflight has invalid HTTP status code 500
core.es5.js:1085 ERROR Response {_body: ProgressEvent, status: 0, ok: false, statusText: "", headers: Headers…}
defaultErrorLogger @ core.es5.js:1085
ErrorHandler.handleError @ core.es5.js:1145
IonicErrorHandler.handleError @ ionic-error-handler.js:63
next @ core.es5.js:4774
schedulerFn @ core.es5.js:3848
SafeSubscriber.__tryOrUnsub @ Subscriber.js:234
SafeSubscriber.next @ Subscriber.js:183
Subscriber._next @ Subscriber.js:125
Subscriber.next @ Subscriber.js:89
Subject.next @ Subject.js:55
EventEmitter.emit @ core.es5.js:3834
NgZone.triggerError @ core.es5.js:4205
onHandleError @ core.es5.js:4166
t.handleError @ polyfills.js:3
n.runTask @ polyfills.js:3
invoke @ polyfills.js:3

Though if I turn off the CORS handler in Chrome, I get:


(index):1 XMLHttpRequest cannot load https://mobile-qa.company.org/webapp/j_security_check. Response for preflight has invalid HTTP status code 500
core.es5.js:1085 ERROR Response {_body: ProgressEvent, status: 0, ok: false, statusText: "", headers: Headers…}
defaultErrorLogger @ core.es5.js:1085
ErrorHandler.handleError @ core.es5.js:1145
IonicErrorHandler.handleError @ ionic-error-handler.js:63
next @ core.es5.js:4774
schedulerFn @ core.es5.js:3848
SafeSubscriber.__tryOrUnsub @ Subscriber.js:234
SafeSubscriber.next @ Subscriber.js:183
Subscriber._next @ Subscriber.js:125
Subscriber.next @ Subscriber.js:89
Subject.next @ Subject.js:55
EventEmitter.emit @ core.es5.js:3834
NgZone.triggerError @ core.es5.js:4205
onHandleError @ core.es5.js:4166
t.handleError @ polyfills.js:3
n.runTask @ polyfills.js:3
invoke @ polyfills.js:3

Does this help anything?

As @luukschoen wrote, you have to take care of that preflight request. There is no way around them, and if a POST or GET in Postman works this doesn’t change anything that your app will require an OPTIONS request to work. This requires changes on the server side, right now it seems to answer OPTIONS requests with a error 500.

Only way around this is to proxy all request through a local server that takes care of the preflight stuff and then forwards the request it received on to the real service. There are services out there like https://crossorigin.me/ that take care of that, but they are REALLY REALLY not meant for production stuff.

Sujan,

This won’t happen on the production stuff, only on my test environment. When the app is compiled and placed on a device, it doesn’t use a local server - that’s just for testing and debugging.

Unfortunately, our organization has blocked crossorigin.me - I tried it yesterday.

I would like to point out that PostMan seems to be able to get around the problem in their code - any idea how they do it?

Jai

They are not a mobile app and probably do similar stuff to what this Chrome plugin did.

The fun stuff is you can actually debug postman by enabling a flag on google chrome. This way you can inspect the posts postman makes, maybe it helps you finding out how they do it. You can read up about enabling chrome developer tools in postman over here:

Could it be that the endpoint that you are posting to expects json while you are posting url encoded parameter values ?
If so, try this :-
On client side,

  1. In headers, set content type to “application/json” instead of form-url-encoded

  2. post serialized data using :-:

this.http.post(‘https://mobile-qa.company.org/webapp/j_security_check’, JSON.stringify(postBody), options)

While presumably well-meaning, the above advice is unnecessary. Angular’s Http client handles content type and stringifying. App code need not and should not do that.