2

I have a really simple HTML page running jQuery that's trying to post to a REST API. Here's my code.

<script type="text/javascript" language="javascript">
    var user = 'someuser';
    var pass = 'somepassword';
    var payload = {
        "value1": "first value",
        "value2": "second value"
    };
    var rootUrl = 'http://someinternalserver:8888/api/Method';
</script>
<script language="javascript" type="text/javascript" id="postWtnBlock">
    function postValue_Go() {
        $.ajax({
            url: rootUrl,
            // Removing the next line or changing the value to 'JSON' results in an OPTIONS request.
            dataType: 'JSONP',
            data: JSON.stringify(payload),
            method: 'POST',
            user: user,
            password: pass,
            beforeSend: function (req) {
                req.setRequestHeader('Authorization', 'BASIC ' + btoa(user + ':' + pass));
            },
            success: function (data) {
                alert(data);
            },
            error: function (xhr) {
                alert(xhr.status + ' ' + xhr.statusText);
            }
        });
    }
</script>

Two things are happening here.

1) Every request is being sent as a GET request, not a POST. 2) The Authorization Header never makes it into the request; it's always missing.

I have no idea why this is.

Update #1: The new postValue_Go() looks like this...

    function postValue_Go() {
        $.ajax({
            url: rootUrl,
            data: JSON.stringify(payload),
            method: 'POST',
            username: user,
            password: pass,
            xhrFields: {
                withCredentials: true
            },
            success: function (data) {
                alert(data);
            },
            error: function (xhr) {
                alert(xhr.status + ' ' + xhr.statusText);
            }
        });
    }

Here's the raw request, captured in Fiddler:

POST http://someinternalserver:8888/api/Method/ HTTP/1.1
Host: someinternalserver:8888
Connection: keep-alive
Content-Length: 693
Accept: */*
Origin: http://devserver
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Referer: http://devserver/samples/ExternalAPI/
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.8
Cookie: someCookieValue=Boo; someOtherCookieValue=Yum;

{"value1": "first value","value2": "second value"}

And the raw response, that too captured in Fiddler.

HTTP/1.1 401 Unauthorized
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/7.5
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Fri, 19 Aug 2016 17:12:29 GMT
Content-Length: 61

{"Message":"Authorization has been denied for this request."}
amber
  • 1,067
  • 3
  • 22
  • 42

1 Answers1

0

It's being sent as a GET request because JSONP appends a script to your webpage with the src attribute pointing to the web service (carrying out the GET request) which then returns the script with the requested data all bundled in a callback function.

Apparently it is possible to perform POST requests through JSONP if you're willing to do some serious leg work with iframes, etc. (see here), but for most intents and purposes you'll be limited to GET requests.

The authorization header is never set because there's currently no way to modify the headers sent for a script to be added to the page.

stevenelberger
  • 1,368
  • 1
  • 10
  • 19
  • If I remove the `JSONP` the generated request becomes an `OPTIONS` request. – amber Aug 18 '16 at 21:48
  • 1
    @amber I believe that's because you're setting custom headers. See [here](https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Preflighted_requests) – stevenelberger Aug 18 '16 at 21:51
  • That did something. I commented out the `beforeSend` handler, actually got a `POST` but the server came back with a 401 Not Authorized. Looking at the raw request, I don't see any authorization information as set with the `user` and `password` setting value. – amber Aug 18 '16 at 21:56
  • 1
    I believe the `user` field should be `username` and you might want to add `xhrFields: { withCredentials: true}` as well, but I'm not too sure about that. – stevenelberger Aug 18 '16 at 22:03
  • Looking up the `Settings` for `$.Ajax`, you are correct, it should be `username`, so that's fixed. I added the xhrField you suggested. I'm still not seeing the authorization header in the request. – amber Aug 19 '16 at 17:22