This is my Node Express Code,
(function () {
'use strict';
var fs = require('fs');
var cors = require('cors');
var bodyParser = require('body-parser');
var express = require('express'),
app = express(),
port = 8112;
app.use(cors());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.listen(port);
app.route('/abc')
.post(abc);
function abc(req,res){
console.dir(req.body);
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
res.sendStatus(200);
}
})();
But Im getting request body as
{}
But in my network Tab in Chrome I can see request payload.
Please note OPTIONS is fired before this POST call.
Request headers
POST /abcHTTP/1.1 Host: localhost:8112 Connection:
keep-alive Content-Length: 11 Pragma: no-cache Cache-Control: no-cache
Origin: http://localhost:4200 User-Agent: Mozilla/5.0 (Windows NT
10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36
x-api-key:CExkxDlFC35ckfCGX6m61x76GxIYH2h2Iv8bX874
Content-Type:text/plain;charset=UTF-8
Accept: / Referer:
http://localhost:4200/dashboard
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Request Payload
{"dd":"dd"}
You need to send: Content-Type: application/json for bodyParser.json() to work, without it, your JSON payload won't be parsed, that's why you get: {}
From the docs:
The bodyParser object exposes various factories to create middlewares.
All middlewares will populate the req.body property with the parsed
body when the Content-Type request header matches the type option, or
an empty object ({}) if there was no body to parse, the Content-Type
was not matched, or an error occurred.
Example using .fetch:
fetch('http://localhost:4200/dashboard', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({dd: 'dd'})
});
Your content-type header is text/plain. Please try replacing
app.use(bodyParser.json());
with
app.use(bodyParser.text());
This normally happens because of the "Content-type" header in your http request.
JSON Bodies
bodyParser.json() only accepts the type of "application/json" and rejects other non-matching content types.
Solutions 1: Accepting Extra Content Types Other Than application/json
check your request header "Content-type" and add it to options argument in bodyParser.json([options]) in server.
for example if you have this:
"Content-type: application/csp-report"
app.use(bodyParser.json({ type: ["application/json", "application/csp-report"] }));
you can also use the built-in middleware in exprss v4.16.0 onwards:
app.use(express.json({ type: ['application/json', 'application/csp-report'] }));
for more information see this documentation
Notice: use this approach only where you can not change Content-type to application/json.
Solutions 2 ( recommended ): Change Header content-type To application/json In Http Request.
What about urlencoded bodies ?
This is similar to json bodies with two differences:
"Content-type" header accepted in request is "application/x-www-form-urlencoded"
body payload is a url encoded format (Not a json object):
Format: param_1=value_1¶m_2=value_2&...
app.use(express.urlencoded({ extended: false }));
see docs.
Hi #Pradhaban Nandhakumar, I think you have to pass data as row data.
Try below code snippets.
You should always pass raw data .
app.post('/users', (req, res) => {
res.send(req.body);
});
You are posting a plain-text string instead of a JSON. Consider showing us how you are posting data (jQuery, Fetch API, etc).
Just have to specify
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
in your request headers (front-end). The Express body parser should then be able to detect the valid JSON and print the result. Note that Accept isn't required but it instructs the server that the client understands and accepts a JSON response.
Alternatively, use a simple library like Easy Fetch on the front-end to manage server-side calls without having to deal with response parsing or header settings.
Related
The Frontend JavaScript sends a CORS fetch POST with login credentials to the backend. However the Set-Cookie (for authentication) in the response from the backend is not stored in the browser, why is that the case?
The Set-Cookie is shown in the fetch response and gets recognized as a http Cookie from the browser, however it doesn't get saved.
I've been through a lot of entries on this issue and checked things like "credentials: 'include'", the correct Response Headers and SameSite properties of the cookie.
Would really appreciate someone's expert opinion, since I couldn't resolve the issue for days now. ;)
This is the webpage for login:
https://www.evs-media.com/tests/t5
For the backend I'm using a Rest API No-Code Tool: https://www.xano.com
Domain Frontend: https://www.evs-media.com
Domain Backend API: https://x8ki-letl-twmt.n7.xano.io/api:s900chrT
On the backend server-side this is what the Request Header looks like:
"Sec-Fetch-Site: cross-site",
"Sec-Fetch-Mode: cors"
"Sec-Fetch-Dest: empty"
"Dnt: 1","Origin: https://www.evs-media.com"
"Content-Type: multipart/form-databoundary=---------------------------32748419764181237672921298736"
"Referer: https://www.evs-media.com/"
"Accept-Encoding: gzip, deflate, br"
"Accept-Language: en-US,en;q=0.5"
"Accept: */*","User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:102.0) Gecko/20100101 Firefox/102.0"
"Content-Length: 295"
"X-Scheme: https"
"X-Forwarded-Scheme: https"
"X-Forwarded-Proto: https"
"X-Forwarded-Port: 443"
"X-Forwarded-Host: x8ki-letl-twmt.n7.xano.io"
"X-Forwarded-For: 79.242.71.235"
"X-Real-Ip: 79.242.71.235"
"X-Request-Id: c459f42dad416f9b5d0d53df307632e9"
"Host: x8ki-letl-twmt.n7.xano.io"
This is the Response Header on the backend server-side:
"Accept-Ranges: none"
"X-XSS-Protection: 1; mode=block"
"X-Frame-Options: deny"
"Access-Control-Allow-Methods: GET, POST, DELETE, PUT, PATCH, OPTIONS, HEAD"
"Access-Control-Allow-Headers: Cache-Control, Content-Type, Content-Length, Authorization, Accept, Accept-Encoding, User-Agent, X-Requested-With, X-APP-KEY, X-Data-Source, X-Branch"
"Access-Control-Allow-Credentials: true"
"Access-Control-Max-Age: 86400"
"X-App: hit"
"set-cookie: myfirstcookie= Bearer eyJhbGciOiJBMjU2S1ciLCJlbmMiOiJBMjU2Q0JDLUhTNTEyIiwiemlwIjoiREVGIn0.jowMcpyEUJZPSxDuIWbGRT2IMabWHfYkBX9tr0_t0agn8wkAKFlc5tUPGpAdKf-9Rhgo8IE5oCwKTNJ0hL1VqZv2D4Vl2XJC.614vZOklc-w9tlAcpxf8Sw.d1OGC6ownAZid1q0XwbGOVP_AKTCMuPG9ehcCbG2iklLHzAeela9r_78t5IN30FwcgHkxNPlh0opQuw5t1DXqjosVTWwgdFzOhv_Add4vznjo_Gd6bv-tnFOLeQVlcfLb3CNzGvHcC8rII9rEy_HjcNx9Xv9DqXIM7i2KPYf33Q.mLjsCPzAUINdZLPydsJyaHNI8v6AISAU8mvz0pRrLw4; Expires=Wed 20 Jul 2022 07:28:00 GMT; Max-Age=2592000; Domain=.x8ki-letl-twmt.n7.xano.io/api:s900chrT; path=/; SameSite=None; Secure; HttpOnly;"
"Access-Control-Allow-Origin: https://www.evs-media.com"
"Access-Control-Expose-Headers: Set-Cookie"
"Content-Type: application/json; charset=UTF-8"
This is what the Request Headers look like on the frontend client-side:
Screeenshot of Request Headers
This is the fetch JavaScript on the frontend:
const myForm = document.getElementById('myForm');
myForm.addEventListener('submit', function (e) {
e.preventDefault();
const formData = new FormData(this);
fetch('https://x8ki-letl-twmt.n7.xano.io/api:s900chrT/auth/logintest', {
method: 'POST',
credentials: 'include' ,
body: formData
}).then(function (response) {
return response.text();
}).then(function (text) {
console.log(text);
}).catch(function (error) {
console.error(error);
})
})
I'm a newbie in Express so for this issue I've researched quite bit but I cannot get it right. So I need to pass an array like this ["1","2","3","4","5"] as a payload from Frontend, and in the Express I need to accept it and do stuff with it. So far, I can send it from Frontend and receive at Express but the content of what I receive does not look right. In the Express I receive:
POST / 200 3.239 ms - 97
{ '"1","2","3","4","5"': '' }
so I cannot do anything with this. I tried to send an object called params and receive that to do something with that, that didn't work either.
Frontend headers are like this
Request URL: http://localhost:5000/
Request Method: POST
Status Code: 200 OK
Remote Address: [::1]:5000
Referrer Policy: strict-origin-when-cross-origin
Access-Control-Allow-Origin: *
Connection: keep-alive
Content-Length: 36
Content-Type: application/json; charset=utf-8
Date: Mon, 13 Dec 2021 23:06:58 GMT
ETag: W/"24-sEnfXlyl7goDTpCx3bZVIGauJsc"
Keep-Alive: timeout=5
X-Powered-By: Express
Accept: application/json, text/plain, */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Connection: keep-alive
Content-Length: 21
Content-Type: application/x-www-form-urlencoded
DNT: 1
Host: localhost:5000
Origin: http://localhost:3000
Referer: http://localhost:3000/
sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="96", "Google Chrome";v="96"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.93 Safari/537.36
Express setup that relates to this is like
var express = require("express");
...
var app = express();
...
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.post("/", (req, res) => {
res.json({ requestBody: req.body });
});
So how can I send as part of the body from frontend in ReactJS an array ["1","2","3","4","5"] then accept that as array in express and do stuff with it?
What you show as the request:
POST / 200 3.239 ms - 97
{ '"1","2","3","4","5"': '' }
And, the headers you show as:
Content-Type: application/x-www-form-urlencoded
Do not match. Your data is being sent as plain text. It's not application/json or application/x-www-form-urlencoded so you don't have a body-parser installed for it so Express doesn't know what to do with it. In fact, Express doesn't even read it, it just stays in the incoming stream.
You don't show the client-side code, but the client needs to make the content-type and the encoding of the body content you send with the POST actually match. Then, you need a body-parser for that content-type on the Express side of things.
Since this is meant to be an array of data, I would suggest using JSON and sending application/json encoded data. Then, your existing express.json() middleware will read and parse it for you and you can read the data in req.body.
If you want help fixing the client-side, then show us the client-side code that is sending this.
For example, if you were sending this from the client with fetch(), here's an example right from the MDN doc for fetch():
// Example POST method implementation:
async function postData(url = '', data = {}) {
// Default options are marked with *
const response = await fetch(url, {
method: 'POST', // *GET, POST, PUT, DELETE, etc.
headers: {'Content-Type': 'application/json'},
body: JSON.stringify(data) // body data type must match "Content-Type" header
});
return response.json(); // parses JSON response into native JavaScript objects
}
postData('https://example.com/answer', { answer: 42 })
.then(data => {
console.log(data); // JSON data parsed by `data.json()` call
});
You should NOT send an object called params. Since its POST request, you should send the array as an property of the request body. Then it will be available in the req.body property in the Express app.
I have some problems with sending a POST request to my REST-API.
The problem is, when I send it from a react application, it shows me this error in the debug console of firefox.
The funny thing is, that it works perfectly fine when sending the request with postman.
This is the code i use to make the request:
let apiURL = API_URL_BASE + "/api/authenticate"
let requestBody = JSON.stringify(
{
"username": this.getEnteredLoginUsername(),
"password": this.getEnteredLoginPassword()
}
);
let headerData = new Headers();
headerData.append('Accept', '*');
headerData.append("Access-Control-Allow", "*");
headerData.append('Content-Type', 'application/json');
headerData.append('Access-Control-Allow-Origin', '*');
headerData.append("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT");
headerData.append("Access-Control-Allow-Headers", "*");
let requestOptions = {
method: 'POST',
mode: 'cors',
redirect: 'follow',
body: requestBody,
headers: headerData
}
this.setState({loadingData: true});
fetch(apiURL, requestOptions).then( response => {
let responseStatus = response.status;
response.json().then( responseJSON => {
});
});
I hope someone can help me with this.
This is the error shown by firefox console: Image
You do seem to have a correct request header from the client-side, i.e the browser, but your server that is hosting the API must also send a response to the client back indicating that it allows cross-origin requests, Otherwise browser would not proceed ahead with your request. Setting cors headers from the server would depend on what framework you're using for the backend. In fact you need to add those cors header you've added here to the server code.
A sample response header would look like this :
HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 00:23:53 GMT
Server: Apache/2
Access-Control-Allow-Origin: * (Note: * means this will allow all domains to request to your server)
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: application/xml
For express, you can follow this link.
More on CORS here
SO my graphql api is at https://gpbaculio-tributeapp.herokuapp.com/graphql I configured the uploaded, headers like this:
const fetchQuery = (operation, variables) => {
return fetch('/graphql', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*'
},
body: JSON.stringify({
query: operation.text,
variables,
}),
}).then(response => {
return response.json()
})
}
I have read from MDN.
For requests without credentials, the server may specify "*" as a
wildcard, thereby allowing any origin to access the resource.
So I am trying to publish the app in codepen, and this is my error:
Failed to load https://gpbaculio-tributeapp.herokuapp.com/graphql:
Response to preflight request doesn't pass access control check: No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'https://s.codepen.io'
Why is it telling me it doesn't pass 'Access-Control-Allow-Origin' headers?
Is there something wrong with my headers config?
You are setting the header in your request (in the client). The Access-Control-Allow-Origin header needs to be set on the server-side, and when you make a request, the response should contain that header.
The reason behind this header is that not every webpage can query every third-party domain. Being able to set this header from the request would defeat that whole point.
Try setting cors options and Access-Control-Allow-Origin headers in server side.
const graphQLServer = express();
const corsOptions = {
origin(origin, callback) {
callback(null, true);
},
credentials: true
};
graphQLServer.use(cors(corsOptions));
var allowCrossDomain = function(req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type');
next();
}
graphQLServer.use(allowCrossDomain);
This may help you
CORS specification states, that requests for resources are "preflighted" with HTTP OPTIONS request, and reply headers for that OPTIONS must contain header:
Access-Control-Allow-Origin: *
you might check it with curl:
$ curl -I -X OPTIONS https://gpbaculio-tributeapp.herokuapp.com/graphql
HTTP/1.1 405 Method Not Allowed
Server: Cowboy
Connection: keep-alive
X-Powered-By: Express
Allow: GET, POST
Content-Type: application/json; charset=utf-8
Content-Length: 97
Date: Sat, 23 Sep 2017 11:24:39 GMT
Via: 1.1 vegur
Add OPTION handler with needed header, so your server answers:
$ curl -I -X OPTIONS https://example.localhost/
HTTP/1.1 204 No Content
Server: nginx/1.4.7
Date: Sat, 23 Sep 2017 11:27:51 GMT
Connection: keep-alive
Keep-Alive: timeout=5
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range
Content-Type: text/plain; charset=utf-8
Content-Length: 0
The problem is the browser's cross-origin problem.
The Access-Control-Allow-Origin header should be return by the server's response, and the header means the origin domain that can access to the API.
The client's request often take a header Origin, it's value is the current host address, like, www.example.com.
The values of Access-Control-Allow-Origin must contain the value of Origin means that the origin can access this API service. And then the browser will continue the request. If not, the browser will cancel the request.
More infomation, refre to CORS https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
I am a novice to angular.js, and I am trying to add some headers to a request:
var config = {headers: {
'Authorization': 'Basic d2VudHdvcnRobWFuOkNoYW5nZV9tZQ==',
'Accept': 'application/json;odata=verbose'
}
};
$http.get('https://www.example.com/ApplicationData.svc/Malls(1)/Retailers', config).success(successCallback).error(errorCallback);
I've looked at all the documentation, and this seems to me like it should be correct.
When I use a local file for the URL in the $http.get, I see the following HTTP request on the network tab in Chrome:
GET /app/data/offers.json HTTP/1.1
Host: www.example.com
Connection: keep-alive
Cache-Control: max-age=0
If-None-Match: "0f0abc9026855b5938797878a03e6889"
Authorization: Basic Y2hhZHN0b25lbWFuOkNoYW5nZV9tZQ==
Accept: application/json;odata=verbose
X-Requested-With: XMLHttpRequest
If-Modified-Since: Sun, 24 Mar 2013 15:58:55 GMT
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.172 Safari/537.22
X-Testing: Testing
Referer: http://www.example.com/app/index.html
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
As you can see, both of the headers were added correctly. But when I change the URL to the one shown in the $http.get above (except using the real address, not example.com), then I get:
OPTIONS /ApplicationData.svc/Malls(1) HTTP/1.1
Host: www.datahost.net
Connection: keep-alive
Access-Control-Request-Method: GET
Origin: http://mpon.site44.com
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.172 Safari/537.22
Access-Control-Request-Headers: accept, origin, x-requested-with, authorization, x-testing
Accept: */*
Referer: http://mpon.site44.com/app/index.html
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
The only difference in code between these two is one is for the first the URL is a local file, and for the second the URL is a remote server. If you look at the second Request header, there is no Authentication header, and the Accept appears to be using a default instead of the one specified. Also, the first line now says OPTIONS instead of GET (although Access-Control-Request-Method is GET).
Any idea what is wrong with the above code, or how to get the additional headers included using when not using a local file as a data source?
I took what you had, and added another X-Testing header
var config = {headers: {
'Authorization': 'Basic d2VudHdvcnRobWFuOkNoYW5nZV9tZQ==',
'Accept': 'application/json;odata=verbose',
"X-Testing" : "testing"
}
};
$http.get("/test", config);
And in the Chrome network tab, I see them being sent.
GET /test HTTP/1.1
Host: localhost:3000
Connection: keep-alive
Accept: application/json;odata=verbose
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_3) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.172 Safari/537.22
Authorization: Basic d2VudHdvcnRobWFuOkNoYW5nZV9tZQ==
X-Testing: testing
Referer: http://localhost:3000/
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
Are you not seeing them from the browser, or on the server? Try the browser tooling or a debug proxy and see what is being sent out.
Basic authentication using HTTP POST method:
$http({
method: 'POST',
url: '/API/authenticate',
data: 'username=' + username + '&password=' + password + '&email=' + email,
headers: {
"Content-Type": "application/x-www-form-urlencoded",
"X-Login-Ajax-call": 'true'
}
}).then(function(response) {
if (response.data == 'ok') {
// success
} else {
// failed
}
});
...and GET method call with header:
$http({
method: 'GET',
url: '/books',
headers: {
'Authorization': 'Basic d2VudHdvcnRobWFuOkNoYW5nZV9tZQ==',
'Accept': 'application/json',
"X-Login-Ajax-call": 'true'
}
}).then(function(response) {
if (response.data == 'ok') {
// success
} else {
// failed
}
});
If you want to add your custom headers to ALL requests, you can change the defaults on $httpProvider to always add this header…
app.config(['$httpProvider', function ($httpProvider) {
$httpProvider.defaults.headers.common = {
'Authorization': 'Basic d2VudHdvcnRobWFuOkNoYW5nZV9tZQ==',
'Accept': 'application/json;odata=verbose'
};
}]);
my suggestion will be add a function call settings like this
inside the function check the header which is appropriate for it. I am sure it will definitely work. it is perfectly working for me.
function getSettings(requestData) {
return {
url: requestData.url,
dataType: requestData.dataType || "json",
data: requestData.data || {},
headers: requestData.headers || {
"accept": "application/json; charset=utf-8",
'Authorization': 'Bearer ' + requestData.token
},
async: requestData.async || "false",
cache: requestData.cache || "false",
success: requestData.success || {},
error: requestData.error || {},
complete: requestData.complete || {},
fail: requestData.fail || {}
};
}
then call your data like this
var requestData = {
url: 'API end point',
data: Your Request Data,
token: Your Token
};
var settings = getSettings(requestData);
settings.method = "POST"; //("Your request type")
return $http(settings);
What you see for OPTIONS request is fine. Authorisation headers are not exposed in it.
But in order for basic auth to work you need to add: withCredentials = true; to your var config.
From the AngularJS $http documentation:
withCredentials - {boolean} - whether to to set the withCredentials
flag on the XHR object. See requests with credentials for more
information.
And what's the answer from the server? It should reply a 204 and then really send the GET you are requesting.
In the OPTIONS the client is checking if the server allows CORS requests. If it gives you something different than a 204 then you should configure your server to send the correct Allow-Origin headers.
The way you are adding headers is the right way to do it.
Chrome is preflighting the request to look for CORS headers. If the request is acceptable, it will then send the real request. If you're doing this cross-domain, you will simply have to deal with it or else find a way to make the request non-cross-domain. This is by design.
Unlike simple requests (discussed above), "preflighted" requests first
send an HTTP request by the OPTIONS method to the resource on the
other domain, in order to determine whether the actual request is safe
to send. Cross-site requests are preflighted like this since they may
have implications to user data. In particular, a request is
preflighted if:
It uses methods other than GET, HEAD or POST. Also, if POST is used to
send request data with a Content-Type other than
application/x-www-form-urlencoded, multipart/form-data, or text/plain,
e.g. if the POST request sends an XML payload to the server using
application/xml or text/xml, then the request is preflighted. It sets
custom headers in the request (e.g. the request uses a header such as
X-PINGOTHER)
Ref: AJAX in Chrome sending OPTIONS instead of GET/POST/PUT/DELETE?
You are just adding a header which server does not allow.
eg - your server is set up CORS to allow these headers only (accept,cache-control,pragma,content-type,origin)
and in your http request you are adding like this
headers: {
'Authorization': 'Basic d2VudHdvcnRobWFuOkNoYW5nZV9tZQ==',
'Accept': 'application/json',
'x-testing': 'testingValue'
}
then the Server will reject this request since (Authorization and x-testing) are not allowed.
This is server side configuration.
And there is nothing to do with HTTP Options, it is just a preflight to server which is from different domain to check if server will allow actual call or not.
For me the following explanatory snippet worked. Perhaps you shouldn't use ' for header name?
{
headers: {
Authorization: "Basic " + getAuthDigest(),
Accept: "text/plain"
}
}
I'm using $http.ajax(), though I wouldn't expect that to be a game changer.