Restangular: How to get HTTP response header? - http-headers

I have a REST server which returns a Link HTTP header with a response to a PUT to indicate the URL of the newly-created entity:
Link:<entities/6>; rel="created"
Is there any possibility to read that link header with Restangular?
The only facility to intercept HTTP requests with Restangular I've met so far is to register a response interceptor in the app config:
restangular.addResponseInterceptor(function (data, operation, what, url, response, deferred) {
console.log(response.headers())
return response.data;
});
However, with above demo implementation in place, the only HTTP header which gets logged is content-type. Still, I can see in the browser development toolbar that a response comes indeed with many additional HTTP response headers, such as Server, Date, and the aforementioned Link.
Why do I not have access to the full array of HTTP response headers through addResponseInterceptor()? Is there any way to capture the HTTP response header in question using Restangular?
Note: I don't search for an answer using HAL or any other special response body format. I would rather like to know whether I can use plain HTTP headers with Restangular or not (if not, I will probably resort to HAL or something).

You don't need a ResponseInterceptor to do this. You just need to set fullResponse to true to get the whole response (including the http headers) every time you do any request.
Restangular.setFullResponse(true);
You can set it globally in your app configuration. Something like this:
angular.module('YourApp')
.config(['RestangularProvider',
function (RestangularProvider) {
RestangularProvider.setFullResponse(true);
...
Then, every time you receive a response, you can access all the response headers.
Restangular.all('users').getList().then(function(response) {
$scope.users = response.data;
console.log(response.headers);
}
Example:
response.headers('Link')
NOTE: Be careful because using fullResponse, the response data is located in response.data, not directly in response.
EDIT: As #STEVER points, you also need to expose the headers in your server API.
Example:
Access-Control-Expose-Headers: Link
You can get more detailed information in Restangular documentation
Hope it helps.

Related

Is there a way to set "Origin" header in server? (Nuxt.js)

I'm developing a Nuxt app that is going to have multiple domains, e.g. example1.com, example2.com, etc (This is handled by nginx)
What is important here, is that the back-end API acts based on the Origin header which is sent from the Nuxt app and sends corresponding data based on Origin.
In nuxtServerInit I'm calling some back-end API to load some data (using axios), but the problem is that Origin header is not being sent to the back-end. It also does not make sense to set Origin manually as window is undefined in that initial API call.
Here's my nuxtServerInit function:
async nuxtServerInit(_vuexContext, { $accessor, error }: Context) {
try {
const config = await this.$axios.$get('/v1/config/')
console.log(config)
} catch (e: any) {
console.error(e)
return error({ statusCode: 500, message: e.message })
}
},
Now I want to know, is there a way to set the Origin header in server?
Is there a workaround for that? Or do you have a better solution for my case?
You can still set the Origin header manually, without access to the window. You’ll find the origin of the original request (eg. example1.com) in the req object, which is available in the Nuxt context (but only on the server side).
I think you know this already, but calling your API from nuxtServerInit generates a new request on the node side— which doesn’t have an origin header by default. You can grab the correct origin from the original request as above, and stick it in a header on the new request.
I’ll assume your use case lends itself to this approach, and you’ve considered alternatives to spoofing the origin of your node-side request.

SmartRule For HTTP

In the Cumulocity guide, https://www.cumulocity.com/guides/event-language/introduction/, there is a mention of Event Streams for HTTP.
HTTP ResponseReceived SendReqeust This group of events represents sending http requests to external services.
This means we can send outbound HTTP request to external services using the "SendRequest" stream. However, I did not find any further details in any documentation. Can you please provide the template CEL details for SendRequest, and how to configure the same in Cumulocity?
I can not help you using the actual engine (Apama) but I can give you one example using Esper.
#Name("Sending the http request")
#Resilient
insert into
SendRequest
select
'post' as method,
'https://tenant.cumulocity.com/inventory/managedObjects' as url,
'Basic .....' as authorization,
'application/json' as contentType,
toJSON(m) as body
from anyEventStream m;
The toJSON if a function that takes the event stream and return is equivalent in json.
You can find more info here. This info is hide from the actual docs and think it is because they want to push developers to use APAMA instead ESPER.
Hope this helps.

How to distinguish between GET and POST

I'm writing a simple api for training using express. Here's my testing code:
var express = require('express');
var app = express();
app.post("/api/:var_name", function(req, res) {
res.send(req.params.var_name);
});
is simply testing to see if POST is working. When I call http://localhost:3000/api/1 I get Cannot GET /api/1, so the server is obviously interpreting the POST request as GET, what do I need to do to call POST instead?
Anything you call in the address bar of your browser will be sent via get. This is due to the fact that post-messages (and almost all other methods) do have a body-part. But there is no way for your browser to send additional information inside the body of the http packet.
If you want to test your routes for any method other than GET I would suggest you download a tool like postman.
https://www.getpostman.com/
BEWARE: This is my preference. You can of curse also use text based browsers like curl to test it.
The server interprets the request according to the verb you set in the HTTP request. If no method/verb is specified it is interpreted as GET(not sure about this part).
When you call that URL, you need to use the method as well. For example if you use the fetch API, you can call it like:
fetch(url, {method:"POST"})
If you're entering it in your browser and expect it to be interpreted as a post request, it's not. All browser url requests are GET. Use a tool like Postman to call different HTTP verbs. It's really useful when creating such APIs.
You can check out this answer on details of how to add body and headers to a post request: Fetch: POST json data

How to set a header (specifically cookie) in the response of a Worklight Adapter Procedure

It's obvious how to set headers accessing a backend system via invokeHttp method, but I can't for the life of my find a way to write a cookie or even write a response header in the response back from the adapter procedure. I'd like to be able to write a Set-Cookie header in the HTTP response back to the client. I also want this to be a true HTTP header, not just part of the JSON body.
This is currently not possible in Worklight. We do have a feature request for it, though, so it may happen some day...
Feel free to add an additional feature request to highlight the need for it: http://www.ibm.com/developerworks/rfe/

jQuery POST does not send JSON data

I'm trying to do a POST to a service running on localhost with jQuery AJAX, but it keeps returning status code 0 even after I've set jQuery.support.cors = true. I can also navigate to my WCF REST service successfully from my browser. This is what my JavaScript looks like:
<script>
jQuery.support.cors = true;
$(document).ready(function(){
$.ajax({
type: "POST",
url: "http://localhost:8000/Test",
data: '{"test":"test"}',
contentType: "application/json",
dataType: "json",
success: function (msg) {
alert('success');
},
error:function(x,e){
if(x.status==0){
alert('error 0');
}
}
});
});
</script>
Does anyone know what could be causing this? I should also mention that I can't POST to anything on localhost using jQuery.
According to Fiddler, the JSON data is not sent, and a HTTP OPTIONS is done instead of a POST.
try this
var dataObj = {test:"test"};
var json = JSON.stringify(dataObj);
then in your ajax call
data: json,
I didn't want to spend anymore time on this issue, so I resorted to using raw HTML form POST as the usage of JSON wasn't essential in my case.
For anyone else having the same issues outlined in the original post, see this thread for an explanation and a solution: Problem sending JSON data from JQuery to WCF REST method
To summarize, your service needs to be able to handle the HTTP OPTIONS method if it is expected to respond to cross domain calls.
You should use a tool like network monitor etc. to see if the browser is asking the server for the allowed headers (using the OPTIONS header request), you may need to supply the correct headers in an OPTIONS response before the actual request is sent to the server (see the article at the bottom).
Also, you could try adding this to the actual call or the ajaxSetup, as you will need to tell the browser to send credentials and allow the cross domain call (I know someone else already mentioned 'crossDomain'):
$.ajaxSetup({
crossDomain: true,
xhrFields: {
withCredentials: true
}
});
Have a read of this if you get time too.. https://developer.mozilla.org/en/http_access_control
So, when the request is cross domain, jQuery will send your post request as a get request anyways.
Are you accessing "localhost" in the URL but then your application is sending the requests to the local IP of your machine instead of localhost? Because that's technically cross-domain, which means that you won't receive the request in the expected manner.
E.g. (just tested this locally)
Visiting my local site at:
http://localhost/test/
A form on the site submits to my local ip address instead of localhost via $.post():
<form action="http://10.0.0.17/test/" method="post">
....[form stuff...]
</form>
This is a cross-domain request
If you're calling $.post() or jquery's ajax() call set to post, it automatically moves your parameters from the post body into the query string.
If you ARE accessing local host, try hitting the site via whatever address your jquery post() method is using as the domain and see if that helps.
See more on cross-domain policies:
http://en.wikipedia.org/wiki/Same_origin_policy
Send the data as an Object literal instead of a string
data: '{"test":"test"}',
to
data: {test:"test"},