How to read HTTP response header values AngularJS - angularjs

Can anyone suggest me how to read the set-cookie value from through angularJS
Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:Origin, Content-Type,Accept, Authorization, X-Requested-With
Access-Control-Allow-Methods:POST, GET, PUT, OPTIONS,DELETE, HEAD
Access-Control-Allow-Origin:*
Access-Control-Expose-Headers:Set-Cookie
Access-Control-Max-Age:3600
Cache-Control:private
Content-Length:274
Content-Type:text/html; charset=utf-8
Date:Fri, 18 Jul 2014 15:09:10 GMT
Server:Microsoft-IIS/7.5
Set-Cookie:.ASPXAUTH=874412C6B46506F2CEB94F14CD64288B50FA245EBAE69E5B7EA0B7BD7BCFBA19DC1EBD1A1D96293561B495B7DAD0FE3E8DB5E82B436E9086EB42F06AE141A5DF141B921CD7D8871C697A2C31F3D6E7AE47FA23FDA276AB380DC4E81C6A200D5244808284A7EA02B8B44F9F048D840D57B470B8E3C22D6A9B857189968A68D3B28340DD4C236A65C9BD3A3B25361383BE429003F9A8DD495B2CFE36785EA982558D6017D40109D8DAE3BB3ECBD9124604; path=/
X-AspNet-Version:4.0.30319
X-AspNetMvc-Version:4.0
X-Powered-By:ASP.NET

My assumption is that you are using $http. If that's the case, it would be something like this:
$http.get(someServiceUrl).then(function (response) {
var foo = response.headers()['Set-Cookie'];
}

Related

Gatling. How to send POST multipart/form-data without file

I try to send POST multipart/form-data but without attached file. It's like the client sends sign up form with email + password and without avatar file(this field isn't required).
HTTP request:
POST https://.../profile/user/own
headers=
Authorization: bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX25hbWUiOiIwN2NjMDUzYS0wMTczLTExZWItOWI1OC0wMTg4NjFhYmViYjAiLCJzY29wZSI6WyJjbGllbnQiXSwiZXhwIjoxNjAxMzc0MzEzLCJ1dWlkIjoiMDdjYzA1M2EtMDE3My0xMWViLTliNTgtMDE4ODYxYWJlYmIwIiwiYXV0aG9yaXRpZXMiOlsiUGF5bWVudE1hcmtldENsaWVudCIsImxvYmJ5X2NoYXQiLCJVc2VyQmFsYW5jZSIsInVzZXItc2xvdC1yZWFkIiwibGVhdmVfY2FsbCIsInJlYWRfc2NoZWR1bGVfdXNlciIsInVzZXItY2FuY2VsLXNsb3QiLCJyZWFkX3VzZXJfcXVlc3Rpb25uYWlyZSIsIndyaXRlX3RpbWV6b25lIiwicmVhZF90aGVyYXBpc3RzX2luZm8iLCJlbmRfc2Vzc2lvbiIsImpvaW5fY2FsbCIsImVkaXRfdXNlciIsImFuc3dlcl9hY3Rpb24iLCJyZWFkX3Nlc3Npb24iLCJQYXltZW50VmVyaWZpQ2xpZW50IiwiYmVnaW5fc2Vzc2lvbiIsIm9jY3VweS1zbG90Iiwid3JpdGVfbWVzc2FnZSIsInJlYWRfdXNlciIsInJlYWRfY29udmVyc2F0aW9uIiwicmVhZF9jaGF0IiwicmVhZF9jdXJyZW50X2NoYXQiLCJzb2NrZXQiLCJtYWtlX2NhbGwiLCJyZWFkX2NhbGwiLCJyZWFkX21lc3NhZ2UiLCJjYWxsX3Rva2VuIl0sImp0aSI6Ijg1NjQ5MmJhLTI0ODUtNDAyZC1hZTJhLWZiY2E2YjhkNGY2MSIsImNsaWVudF9pZCI6ImNsaWVudCJ9.APWse9P8SIJtDMMay8UTT9CN_JEvSIRaznn8JALcYfxz107IaL5ezwEJfIEDBb9_WEDeVKvpjI1eUmiYBQiOcF5LkIPhpww_8vaSbWvWP3Tkg21QQceNEZwnjucMc6Doj1YNlx3iOs03Mv8zmOJZ2S1acz5sVj5cK_ufrItG7Ic_-bbpW67Byl1vNgbTgaJoGMRAgqfCxKpAVpxMFqNw3F8FMKe0dm-uYmJwpKlWVg4sEUOW7LSZ6wr3c5XgBHXVvTzVFb0sJyhFkw9W1nrMSJTxJqsaVGEzIe01qhQZasbRkMxC32XXlFzpGSmBDJpdWpTD3pUXrIhD4v15PWt3wg
accept: */*
host: api.dev.psychicbook.net
content-type: multipart/form-data
content-length: 108
formBody=
userData: {"email":"automation.tku1fin9av3#test.com","nickname":"5SkHTB0EVs"}
=========================
HTTP response:
status=
500
headers=
Server: nginx/1.17.10
Date: Mon, 28 Sep 2020 10:11:53 GMT
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET,POST,PUT,PATCH,DELETE,OPTIONS
Access-Control-Max-Age: 3600
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Allow-Credentials: true
X-Application-Context: gateway-service:develop:8765
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Strict-Transport-Security: max-age=15724800; includeSubDomains
body=
{"timestamp":1601287913987,"status":500,"error":"Internal Server Error","exception":"org.springframework.web.multipart.MultipartException","message":"Could not parse multipart servlet request; nested exception is java.io.IOException: org.apache.tomcat.util.http.fileupload.FileUploadException: the request was rejected because no multipart boundary was found","path":"/profile/user/own"}
There is a special method for file uploading -> .formUpload("file", "image.jpg"), but I don't want to send any file.
If I make the same with Insomnia or anoter REST client, everything is OK, and it looks like:
HttpResponse<String> response = Unirest.post("https://.../profile/user/own")
.header("authorization", "bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX25hbWUiOiJjMGRlNWI3ZS0wMTYzLTExZWItOWI1OC0wMTg4NjFhYmViYjAiLCJzY29wZSI6WyJjbGllbnQiXSwiZXhwIjoxNjAxMzY3NzUyLCJ1dWlkIjoiYzBkZTViN2UtMDE2My0xMWViLTliNTgtMDE4ODYxYWJlYmIwIiwiYXV0aG9yaXRpZXMiOlsiUGF5bWVudE1hcmtldENsaWVudCIsImxvYmJ5X2NoYXQiLCJVc2VyQmFsYW5jZSIsInVzZXItc2xvdC1yZWFkIiwibGVhdmVfY2FsbCIsInJlYWRfc2NoZWR1bGVfdXNlciIsInVzZXItY2FuY2VsLXNsb3QiLCJyZWFkX3VzZXJfcXVlc3Rpb25uYWlyZSIsIndyaXRlX3RpbWV6b25lIiwicmVhZF90aGVyYXBpc3RzX2luZm8iLCJlbmRfc2Vzc2lvbiIsImpvaW5fY2FsbCIsImVkaXRfdXNlciIsImFuc3dlcl9hY3Rpb24iLCJyZWFkX3Nlc3Npb24iLCJQYXltZW50VmVyaWZpQ2xpZW50IiwiYmVnaW5fc2Vzc2lvbiIsIm9jY3VweS1zbG90Iiwid3JpdGVfbWVzc2FnZSIsInJlYWRfdXNlciIsInJlYWRfY29udmVyc2F0aW9uIiwicmVhZF9jaGF0IiwicmVhZF9jdXJyZW50X2NoYXQiLCJzb2NrZXQiLCJtYWtlX2NhbGwiLCJyZWFkX2NhbGwiLCJyZWFkX21lc3NhZ2UiLCJjYWxsX3Rva2VuIl0sImp0aSI6Ijg5ZDg4OTViLTU1NzQtNDk2OC1hNmJhLWRmZjcyYmIxYWI1MyIsImNsaWVudF9pZCI6ImNsaWVudCJ9.bW7F65elarJNQ9RkfIJcH0uq9Og0ue8TXNZ7Gh_FFCdj_c8SVHlPXwu-nEoZZSTVk3gBB2I_hw8MqPfCZVZrlAlzyIfAcyuQ1WRgRH5-xVzYej3XqBEADuCjBabcO87LoPwz_vYCT3JZVhNZHcDMOkQ429dg0HdKeSBd6qJaPYCgWgq529b9-wnufNBx9LHyaTYLWZC5nMfmDbyep3sc2_q6YzqKMMH5a-s1SmOgQpKbCNyCx7gui3tiYqQh21zMN-PhtkRNAD78awzpIpZhuZTF-AbrQkI6J1Yvsg59AYkZZVBd5gyCSopydquezf7xaAc3Ot2L-DubGzWwr2u9gA")
.header("content-type", "multipart/form-data; boundary=---011000010111000001101001")
.body("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"userData\"\r\n\r\n{\"email\":\"automation.tku1fin9av3#test.com\",\"nickname\":\"qatest5\"}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"\r\n\r\n\r\n-----011000010111000001101001--\r\n")
.asString();
How can I make the same but with Gatling?
I had the same issue. I have some entries with, and some without files. Both need to be uploaded using body parts.
When i set one fields using StringBodyPart it worked for me:
val uploadDocument = doIfEqualsOrElse(session => session("file").as[String], "") {
// executed if the session value stored in "myKey" starts with "admin"
exec(
http("upload: ${title}")
.post(
clientPortalUrl + "/customerportal/api/documents"
)
.headers(multipartUploadHeaders)
//if we do not call formUpload() we need set one field using StringBodyPart, the rest will follow.
.bodyPart(StringBodyPart("title", "${title}")).asMultipartForm
.formParam("documentType", "${documentType}")
.formParam("accountId", "${accountId}")
.formParam("period", "${period}")
.formParam("endDate", "${endDate}")
.formParam("signer", "${signer}")
.formParam("nexusRecipient", "${nexusRecipient}")
.formParam("vatFiscalEntityDivision", "${vatFiscalEntityDivision}")
.formParam("editor", "${editor}")
.formParam("repeatable", "${repeatable}")
.requestTimeout(5.minutes)
.check(status.is(201))
.check(jsonPath("$.title").exists)
)
} {
exec(
http("upload: ${title}")
.post(
clientPortalUrl + "/customerportal/api/documents"
)
.headers(multipartUploadHeaders)
.formParam("title", "${title}")
.formParam("documentType", "${documentType}")
.formParam("accountId", "${accountId}")
.formParam("period", "${period}")
.formParam("endDate", "${endDate}")
.formParam("signer", "${signer}")
.formParam("nexusRecipient", "${nexusRecipient}")
.formParam("vatFiscalEntityDivision", "${vatFiscalEntityDivision}")
.formParam("editor", "${editor}")
.formParam("repeatable", "${repeatable}")
.formUpload("files[]", "${file}")
.requestTimeout(5.minutes)
.check(status.is(201))
.check(jsonPath("$.title").exists)
)
}

X-AUTH-TOKEN returns null even though it is present in header

I am using angular JS to login to my app. On the server, it returns a X-AUTH-TOKEN. When I do a JSON request. The header response looks like this...
Pragma: no-cache
Date: Thu, 19 Nov 2015 12:44:05 GMT
X-Content-Type-Options: nosniff
Server: Apache-Coyote/1.1
X-Frame-Options: DENY
Access-Control-Max-Age: 3600
Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE
Access-Control-Allow-Origin: chrome-extension://gmodihnfibbjdecbanmpmbmeffnmloel
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
X-AUTH-TOKEN: eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJiaWxseWpvZSJ9.le0y_pOfQAyLJO4IJ4ZjQQqgqgiN2xtpLAzORawoDm4O4euHFh32LtjMrBUTkr8G2LeY_2bALe_rcm3LY_NlSg
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: Content-Type, Accept, X-Requested-With, remember-me
Content-Length: 88
X-XSS-Protection: 1; mode=block
Expires: 0
As you can see. X-AUTH-TOKEN is present. But when I try to retrieve it and save it to local storage...
$http.post(loginUrl)
.success(function(data, status,headers) {
$scope.hello = data;
var TOKEN = headers("X-AUTH-TOKEN");
window.localStorage['X-AUTH-TOKEN-TRIVIA'] = headers("X-AUTH-TOKEN");
})
It always returns NULL. Why is it not retrieving the token if its clearly in the header ?
I have also used single quotes.
$http.post(loginUrl)
.success(function(data, status,headers) {
$scope.hello = data;
var TOKEN = headers('X-AUTH-TOKEN');
window.localStorage['X-AUTH-TOKEN-TRIVIA'] = headers('X-AUTH-TOKEN');
})
Figured it out... Thanks to another post
Angular.js saying custom HTTP response header is null
The problem is server side. You must add Access-Control-Expose-Headers: X-Auth-Token
In my case using Spring Boot or Spring. You probably would have to add this in your CorsFilter
response.setHeader("Access-Control-Expose-Headers", "X-Auth-Token");

Angularjs $http.post() is sending an OPTIONS request only

I've got some Angular code where I am attempting to send a POST to a dev server.
var url = 'http://someDevUrl.com',
data = { 'someKey': 'some value' };
$http.post(url, data);
It sends the OPTIONS preflight request. I can see it hit the server, and the server gives it a happy response.
OPTIONS Response Headers:
HTTP/1.1 200 OK
Server: Cowboy
Date: Mon, 08 Dec 2014 18:20:44 GMT
Connection: close
Access-Control-Allow-Origin: *
Access-Control-Max-Age: 30
Access-Control-Allow-Headers: x-requested-with, content-type, accept, origin, authorization, x-csrftoken
Content-Type: text/html; charset=utf-8
Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE, OPTIONS
Via: 1.1 vegur
but then Angular never sends the POST after that...
Typically when $http.post() only sends an OPTIONS request, that means the OPTIONS request returned an error (usually a CORS issue). But in this case, all is fine with the OPTIONS request & response, but it still won't send the POST.
Has anyone seen this before or have an idea of what might be preventing it from sending the POST?
EDIT:
I've got around the issue by adding a Content-Type: text/plain header to the request:
var url = 'http://someDevUrl.com',
data = { 'someKey': 'some value' },
config = {
headers: {
'Content-Type': 'text/plain'
}
}
};
$http.post(url, data, config);
which causes it to skip the OPTIONS preflight, thus avoiding the issue. I'm still curious to know why it was not working in the first place, since there was/is no CORS issue and the OPTIONS request was not sending back an error response.

Angular CORS requests fail to Laravel backend, but preflight look good

In short, I'm posting data with Angular to a Laravel backend. The OPTIONS/preflight request looks good, but the subsequent POST fails saying that Access-Control-Allow-Origin header is missing from the requested resource.
I'm using Laravel 5 with Angular 1.2.26. Some further documentation on the backend middleware can be found here: https://laracasts.com/discuss/channels/requests/laravel-5-cors-headers-with-filters.
Laravel middleware:
public function handle($request, Closure $next)
{
return $next($request)->header('Access-Control-Allow-Origin' , 'http://laravel.app:8001')
->header('Access-Control-Allow-Credentials', 'true')
->header('Access-Control-Allow-Methods', 'POST, GET, OPTIONS, PUT, DELETE')
->header('Access-Control-Allow-Headers', 'Content-Type, Accept, Authorization, X-Requested-With')
->header('Access-Control-Max-Age', '28800');
}
Angular config - I've tried with various combinations of the commented code, same results each time:
$httpProvider.defaults.useXDomain = true;
//$httpProvider.defaults.withCredentials = true;
//delete $httpProvider.defaults.headers.common["X-Requested-With"];
//$httpProvider.defaults.headers.common["Accept"] = "application/json";
//$httpProvider.defaults.headers.common["Content-Type"] = "application/json";
Preflight/OPTIONS:
Remote Address:127.0.0.1:8000
Request URL:http://laravel.app:8000/api/v1/authentication/login
Request Method:OPTIONS
Status Code:200 OK
Request Headers
Accept:*/*
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:accept, content-type
Access-Control-Request-Method:POST
Connection:keep-alive
Host:laravel.app:8000
Origin:http://laravel.app:8001
Referer:http://laravel.app:8001/
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.65 Safari/537.36
Response Headers
Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:Content-Type, Accept, Authorization, X-Requested-With
Access-Control-Allow-Methods:POST, GET, OPTIONS, PUT, DELETE
Access-Control-Allow-Origin:http://laravel.app:8001
Access-Control-Max-Age:28800
Allow:GET,HEAD,POST
Cache-Control:no-cache
Connection:keep-alive
Content-Encoding:gzip
Content-Type:text/html; charset=UTF-8
Date:Mon, 24 Nov 2014 16:01:57 GMT
Server:nginx/1.6.2
Set-Cookie:laravel_session=blahblah; expires=Mon, 24-Nov-2014 18:01:57 GMT; Max-Age=7200; path=/; httponly
Set-Cookie:XSRF-TOKEN=blahblah; expires=Thu, 01-Jan-1970 00:02:00 GMT; Max-Age=-1416844797; path=/; httponly
Transfer-Encoding:chunked
POST:
Remote Address:127.0.0.1:8000
Request URL:http://laravel.app:8000/api/v1/authentication/login
Request Method:POST
Status Code:500 Internal Server Error
Request Headers
Accept:application/json, text/plain, */*
Accept-Encoding:gzip, deflate
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
Content-Length:47
Content-Type:application/json;charset=UTF-8
Host:laravel.app:8000
Origin:http://laravel.app:8001
Referer:http://laravel.app:8001/
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.65 Safari/537.36
Request Payload
{email: "x", password: "x", rememberMe: false}
email: "x"
password: "x"
rememberMe: false
Response Headers
Cache-Control:no-cache
Connection:keep-alive
Content-Type:text/html; charset=UTF-8
Date:Mon, 24 Nov 2014 16:01:57 GMT
Server:nginx/1.6.2
Transfer-Encoding:chunked
After stepping through the VerifyCsrfToken middleware I've established that it was indeed a token mismatch.
The reason is that Angular was not supplying the CSRF token via header or via a parameter in the post. It worked for GET and OPTIONS requests because these do not validate against the token.
So, I looked into Angular and there is documentation on XSRF Protection (see https://docs.angularjs.org/api/ng/service/$http) and lots of discussion out there on how to add the appropriate headers (e.g. https://github.com/angular/angular.js/issues/5122#issuecomment-36157820).
I haven't had a chance to follow any of this up as I have to keep my project moving and my particular use case allows me to get away with disabling VerifyCsrfToken as I only need CORS whilst in development.
But hopefully this will give someone else a starting point for solving this issue more fully.
I am unsure if this is an issue with Laravel and the VerifyCsrfToken middleware or not, but the root cause of my issue was that the CSRF token validation was failing. When the error was thrown, the new headers were not included. I'm unclear on the order that these middlewares run in, perhaps that's it, but nonetheless, once I removed the VerifyCsrfToken from the middleware stack, everything lit up.
I had seme problem. If you use middleware to set Headers, but create a new Response, Response::json(), Response::make(), etc. on controller, this new object don't get the headers set by middleware.
I had same problem.
In CORS middleware
Add the following header.
public function handle($request, Closure $next)
{
//All the domains you want to whitelist
$trusted_domains = ["http://localhost:4200", "http://127.0.0.1:4200", "http://localhost:3000", "http://127.0.0.1:3000"];
if (isset($request->server()['HTTP_ORIGIN'])) {
$origin = $request->server()['HTTP_ORIGIN'];
if (in_array($origin, $trusted_domains)) {
header('Access-Control-Allow-Origin: ' . $origin);
header('Access-Control-Allow-Headers: Origin, Content-Type, Authorization, X-Auth-Token,x-xsrf-token');
header('Access-Control-Allow-Methods', 'POST, GET, OPTIONS, PUT, DELETE');
}
}
return $next($request);
}

Angular $http doesn't turn all response headers

I would like to get the 'X-Total-Count' response header of a RESTful API. While trying to get the header in the query callback function of my ngResource 'User', it seems that $http ignores a lot of the reponse headers.
These are the response headers of my request:
Access-Control-Allow-Origin: *
Cache-Control: max-age=0, private, must-revalidate
Connection: close
Content-Encoding: gzip
Content-Type: application/json; charset=utf-8
Date: Fri, 17 Oct 2014 11:13:26 GMT
Link: <http://xxxx.xxx/user?page=2>; rel="next"
Transfer-Encoding: chunked
Vary: Accept-Encoding
X-Total-Count: 32
Here I'm querying the set of users:
User.query({
page: $scope.pagingOptions.currentPage,
limit: $scope.pagingOptions.pageSize
}, function(users, responseHeaders) {
console.log(responseHeaders());
console.log(responseHeaders('X-Total-Count'));
});
That's the result of the console:
Object { cache-control="max-age=0, private, must-revalidate", content-type="application/json; charset=utf-8"}
null
So why the $http's responseHeaders() function turns only 2 of 10 header properties?
Are you sure you are not doing cross origin resource sharing?
see 7.1.1 Handling a Response to a Cross-Origin Request
That specification forbids access to any response header field other
except the simple response header fields (i.e. Cache-Control,
Content-Type, ...)

Resources