set user-agent header on serving index.html, express.js - javascript

I need to set my custom http 'User-Agent header when I'm rendering my index.html page in Express.js app.
This doesn't help:
req.headers['user-agent'] = 'myHeader';
Is this possible?

The User-Agent header is sent by an HTTP client(browser) and is meant to be read by a server, for e.g., for Content Negotiation.
You cannot set a request header in a response, it can only be read. Moreover, the req object(IncomingMessage) passed to createServer() callback is a Readable stream.
However, a request can be initiated with a customer header using:
var headers = {'User-Agent': 'Ryan Dahl'};
http.request({hostname: 'nodejs.org', headers: headers}, function(res) {
});

Related

JxBrowser get post body in custom ProtocolHandler

In one of my projects I use the JxBrowser in a Netbeans application where my ReactApp is running.
I want to send a post request from the ReactApp and intercept it in my custom Protocol Handler in the JxBrowser.
The request is done via 'superagent':
request
.post('http://my-url')
.send({test: 'it'})
.set('Accept', 'application/json')
.set('Content-Type', 'application/json')
.end(callback)
I receive the request in my ProtocolHandler but I do not know how to get the post body out of the request.
urlRequest.getUploadData() //<-- returns null
What is the correct way to get the posts body here?
You're making a cross-origin request. A preflight "OPTIONS" request is sent in this case and you need to handle it properly in your ProtocolHandler. In this particular case you should set the certain headers telling the browser that the requested features are allowed:
if (request.getMethod().equals("OPTIONS")) {
URLResponse urlResponse = new URLResponse();
String origin = request.getRequestHeaders().getHeader("Origin");
HttpHeadersEx headers = urlResponse.getHeaders();
headers.setHeader("Access-Control-Allow-Methods", "POST");
headers.setHeader("Access-Control-Allow-Headers", "Content-Type");
headers.setHeader("Access-Control-Allow-Origin", origin);
urlResponse.setStatus(HttpStatus.OK);
return urlResponse;
}
Also, in order to allow JxBrowser to detect the POST data type properly, you should set the "Content-Type" request header with the corresponding value. In this case it should be the "application/x-www-form-urlencoded".
request
.post('http://my-url')
.send({test: 'it'})
.set('Accept', 'application/json')
.set('Content-Type', 'application/x-www-form-urlencoded')
.end(callback)
Then you'll receive a POST request with your data. I recommend that you take a look at the following article that contains the details related to CORS: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
If you're making a request to the same origin, you can avoid handling cross-origin requests just by setting the proper "Content-Type" header.

Accessing custom http response headers in angularjs

I am trying to access the header 'error-detail' as you can see in the browser network inspector (link above), the header gets returned. Server-wise I have also added the custom header to the 'Access-Control-Expose-Headers' to allow cross-domain requests as this was suggested to be the fix on other questions.
Below is the request to the server along with the success/error callbacks.
this.signon = function (request, onComplete, onError) {
console.log("Calling server with 'login' request...");
return $http.post("http://localhost:8080/markit-war/services/rest/UserService/login/", request)
.then(onComplete, onError);
};
var onLookupComplete = function(response) {
if (response.data.username)
{
//If user is returned, redirect to the dashboard.
$location.path('/dashboard');
}
$scope.username = response.data.username;
};
var onError = function(response) {
$scope.error = "Ooops, something went wrong..";
console.log('error-detail: ' + response.headers('error-detail'));
};
When I try access the response header as seen below:
console.log(response.headers());
console.log('error-detail: ' + response.headers('error-detail'));
This only outputs:
content-type: "application/json"
error-detail: null
Is there a reason why the error-detail header is not being mapped over to the response object?
I think you are on the right track. To have access to custom headers, your server needs to set this special Access-Control-Expose-Headers header, otherwise your browser will only allow access to 6 predefined header values as listed in the Mozilla docs.
In your screenshot such a header is not present in the response. You should have a look at the backend for this cors header to also be present in the response.
This is a CORS Issue. Because this is a cross-origin request, the browser is hiding most ot the headers. The server needs to include a Access-Control-Expose-Headers header in its response.
The Access-Control-Expose-Headers1 response header indicates which headers can be exposed as part of the response by listing their names.
By default, only the 6 simple response headers are exposed:
Cache-Control
Content-Language
Content-Type
Expires
Last-Modified
Pragma
If you want clients to be able to access other headers, you have to list them using the Access-Control-Expose-Headers header.
For more information, see MDN HTTP Header -- Access-Control-Expose-Headers

Send cookie in HTTP POST Request in javascript

I am trying to make a POST request to the server (Which is a REST service)via javascript,and in my request i want to send a cookie.My below code is not working ,as I am not able to receive cookie at the server side.Below are my client side and server side code.
Client side :
var client = new XMLHttpRequest();
var request_data=JSON.stringify(data);
var endPoint="http://localhost:8080/pcap";
var cookie="session=abc";
client.open("POST", endPoint, false);//This Post will become put
client.setRequestHeader("Accept", "application/json");
client.setRequestHeader("Content-Type","application/json");
client.setRequestHeader("Set-Cookie","session=abc");
client.setRequestHeader("Cookie",cookie);
client.send(request_data);
Server Side:
public #ResponseBody ResponseEntity getPcap(HttpServletRequest request,#RequestBody PcapParameters pcap_params ){
Cookie cookies[]=request.getCookies();//Its coming as NULL
String cook=request.getHeader("Cookie");//Its coming as NULL
}
See the documentation:
Terminate these steps if header is a case-insensitive match for one of the following headers … Cookie
You cannot explicitly set a Cookie header using XHR.
It looks like you are making a cross origin request (you are using an absolute URI).
You can set withCredentials to include cookies.
True when user credentials are to be included in a cross-origin request. False when they are to be excluded in a cross-origin request and when cookies are to be ignored in its response. Initially false.
Such:
client.withCredentials = true;
This will only work if http://localhost:8080 has set a cookie using one of the supported methods (such as in an HTTP Set-Cookie response header).
Failing that, you will have to encode the data you wanted to put in the cookie somewhere else.
This can also be done with the more modern fetch
fetch(url, {
method: 'POST',
credentials: 'include'
//other options
}).then(response => console.log("Response status: ", response.status));

Angular $http.post and No 'Access-Control-Allow-Origin' header

I have two app with nodejs and angularjs.nodejs app has some code like this :
require('http').createServer(function(req, res) {
req.setEncoding('utf8');
var body = '';
var result = '';
req.on('data', function(data) {
// console.log("ONDATA");
//var _data = parseInput( data,req.url.toString());
var _data = parseInputForClient(data, req.url.toString());
switch (req.url.toString()) {
case "/cubes":
{
and this app host on http://localhost:4000.angularjs app host with node http-server module on localhost://www.localhost:3030.in one of my angularjs service i have some thing like this :
fetch:function(){
var data = '{somedata:"somedata"}';
return $http.post('http://localhost:4000/cubes',data).success(function(cubes){
console.log(cubes);
});
}
but when this service send a request to server get this error:
XMLHttpRequest cannot load http://localhost:4000/cubes. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3030' is therefore not allowed access.
so i search the web and stackoverflow to find some topic and i find this and this . according to these topics i change the header of response in the server to something like this :
res.writeHead(200, {
'Content-Type': 'application/json',
"Access-Control-Allow-Origin": "*"
});
res.end(JSON.stringify(result));
but this dose'nt work.I try with firefox,chrome and also check the request with Telerik Fiddler Web Debugger but the server still pending and i get the Access Control Allow Origin error.
You do POST request, which generates preflight request according to CORS specification: http://hacks.mozilla.org/2009/07/cross-site-xmlhttprequest-with-cors/ and https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
Your server should also respond to OPTIONS method (besides POST), and return Access-Control-Allow-Origin there too.
You can see it's the cause, because when your code creates request in Network tab (or in Fiddler proxy debugger) you should see OPTIONS request with ORIGIN header

Backbone POST JSON

I am new to Backbone and got the GET working with a test endpoint e.g.,
var Attributes = Backbone.Collection.extend({
url: '//127.0.0.1:8080/blah'
});
var AttributeListView = Backbone.View.extend({
el: '.page',
render: function () {
var that = this;
var attributes = new Attributes();
attributes.fetch({
success: function (attributes) {
var template = _.template($('#attribute-list-template').html(), {attributes: attributes.models});
that.$el.html(template);
}
})
}
})
However, the real endpoint requires a POST with JSON payload and I can't get the syntax to work. I tried something like this
var AttributeListView = Backbone.View.extend({
el: '.page',
render: function () {
var that = this;
var attributes = new Attributes();
attributes.fetch({
type: "POST",
contentType: "application/json; charset=utf-8",
dataType: "json",
data: '{ "searchtext": "abc" }',
success: function (attributes) {
var template = _.template($('#attribute-list-template').html(), {attributes: attributes.models});
that.$el.html(template);
}
})
}
})
#Rusty, the URL works fine with or without http, browsers nowadays handle it properly. After digging a bit more, it seems like it is a CORS issue. I know that the endpoint has set Access-Control-Allow-Origin:* but only for POST request and I don't think the request is being set properly, here's what I got from Chrome debug
Request URL:http://127.0.0.1:8080/blah
Request Headers CAUTION: Provisional headers are shown.
Accept:application/json, text/javascript, */*; q=0.01
Cache-Control:max-age=0
Content-Type:application/x-www-form-urlencoded; charset=UTF-8
Origin:http://localhost:8000
Referer:http://localhost:8000/
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.102 Safari/537.36
Form Dataview sourceview URL encoded
{ "searchtext": "abc" }:
From the console log
XMLHttpRequest cannot load http://127.0.0.1:8080/blah. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8000' is therefore not allowed access.
As you said this is a CORS issue.
Specifically on POST PUT and DELETE requests the browser actually performs 2 requests.
What happens under the hood is that, before the real request, the browser sends a preflight OPTION request which is like asking the server for permission to make the actual request.
(Please checks on the server log which type of request comes from the browser)
To allow CORS request the server must correctly handle this scenario and respond to the OPTION request with a set of CORS Headers like those:
Access-Control-Allow-Origin: http://some.another.domain
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: Content-Type
Content-Type: text/html; charset=utf-8
In the CORS Headers (all begin with Access-Control-Allow-*) the server specifies the following permissions:
Which domain is allowed to perform the request, it can be * to allow any external domain.
Which HTTP Methods are accepted from those domains.
Which Request Headers are accepted, you can add all the headers you need.
For example to handle HTTP Authentication between different domains, which is a common scenario using external API you'll need to add the Authorization header.
If the server responds correctly to the OPTION request the browser will performs the the actual request.
This is a guide to correctly handle CORS Requests for Rails but the it easily applies to all the server side languages/frameworks: http://leopard.in.ua/2012/07/08/using-cors-with-rails/
Rustytoms in his comment is correct. You don't have to set the entire url, you could just write /blah but I think the problem you are having is different.
By default, when you call fetch on a new model Backbone will generate a GET request to get the information following the REST principles. To check whether the model is new Backbone uses the model.isNew() method, which basically just checks if the model has an id. If you call the save() method on a Model then Backbone will generate a POST request to '/users', and if the model is not new it will generate a SYNC request to '/users/:id'.
This methods delegate all the functionality to the Backbone.sync() method. So what you can do if you back end API does not follow the REST principle is to replace the fetch() method in your model with an AJAX call, or create a new one. On the 'success' of the AJAX request you can usemodel.set() to save your attributes to the model.
I suggest you read the Backbone documentation to get to know this methods since everything is very clear.

Categories