Is there anyway we can navigate (via <a/> click) to a URL with additional header in the request ? here's my code :
i have an <a href="#" id="aUsers"/> tag, and then i handle the onClick() event via JQuery :
$('#aUsers').click(function () {
var spAuthData = sessionStorage.getItem('sp-auth-data');
window.location.href = '/users.html?sp-auth-data' = spAuthData;
});
I want to put the spAuthData value in the authorization header, so i can have a clean URL
As far as I know, there is no way to manipulate HTTP headers with a plain url.
You can use headers parameter of jQuery AJAX request if it is suitable in your situation. For example, you can update the contents of some divs with AJAX HTML response.
$.ajax({
url: '/users.html',
headers: { 'Authorization': spAuthData }
}).done(function()
{
});
Otherwise, it looks like you need to make some server-side changes.
But why don't you use cookies or something like this?
Authorization is used only by unauthorized users during authorization. In my opinion, sending this header on every request from the browser manually sounds bad. The best approach is to send this header once during authorization, create a user session and store it in cookies (as an access-token, forms ticket or whatever else).
Related
How can I set a custom field in POST header on submit a form?
It cannot be done - AFAIK.
However you may use for example jquery (although you can do it with plain javascript) to serialize the form and send (using AJAX) while adding your custom header.
Look at the jquery serialize which changes an HTML FORM into form-url-encoded values ready for POST.
UPDATE
My suggestion is to include either
a hidden form element
a query string parameter
Set a cookie value on the page, and then read it back server side.
You won't be able to set a specific header, but the value will be accessible in the headers section and not the content body.
From FormData documention:
XMLHttpRequest Level 2 adds support for the new FormData interface. FormData objects provide a way to easily construct a set of key/value pairs representing form fields and their values, which can then be easily sent using the XMLHttpRequest send() method.
With an XMLHttpRequest you can set the custom headers and then do the POST.
In fact a better way to do it to save a cookie on the client side. Then the cookie is automatically sent with every page header for that particular domain.
In node-js, you can set up and use cookies with cookie-parser.
an example:
res.cookie('token', "xyz....", { httpOnly: true });
Now you can access this :
app.get('/',function(req, res){
var token = req.cookies.token
});
Note that httpOnly:true ensures that the cookie is usually not accessible manually or through javascript and only browser can access it.
If you want to send some headers or security tokens with a form post, and not through ajax, in most situation this can be considered a secure way. Although make sure that the data is sent over secure protocol /ssl if you are storing some sensitive user related info which is usually the case.
Here is what I did in pub/jade
extends layout
block content
script(src="/jquery/dist/jquery.js")
script.
function doThePost() {
var jqXHR = $.ajax({
type:'post'
, url:<blabla>
, headers: {
'x-custom1': 'blabla'
, 'x-custom2': 'blabla'
, 'content-type': 'application/json'
}
, data: {
'id': 123456, blabla
}
})
.done(function(data, status, req) { console.log("done", data, status, req); })
.fail(function(req, status, err) { console.log("fail", req, status, err); });
}
h1= title
button(onclick='doThePost()') Click
You could use $.ajax to avoid the natural behaviour of <form method="POST">.
You could, for example, add an event to the submission button and treat the POST request as AJAX.
If you are using JQuery with Form plugin, you can use:
$('#myForm').ajaxSubmit({
headers: {
"foo": "bar"
}
});
Source: https://stackoverflow.com/a/31955515/9469069
To add into every ajax request, I have answered it here:
https://stackoverflow.com/a/58964440/1909708
To add into particular ajax requests, this' how I implemented:
var token_value = $("meta[name='_csrf']").attr("content");
var token_header = $("meta[name='_csrf_header']").attr("content");
$.ajax("some-endpoint.do", {
method: "POST",
beforeSend: function(xhr) {
xhr.setRequestHeader(token_header, token_value);
},
data: {form_field: $("#form_field").val()},
success: doSomethingFunction,
dataType: "json"
});
You must add the meta elements in the JSP, e.g.
<html>
<head>
<!-- default header name is X-CSRF-TOKEN -->
<meta name="_csrf_header" content="${_csrf.headerName}"/>
<meta name="_csrf" content="${_csrf.token}"/>
To add to a form submission (synchronous) request, I have answered it here:
https://stackoverflow.com/a/58965526/1909708
I simply want to know if the request coming in is a standard page load or if the request has come from an ajax request.
Basically, I would like to use the same controller for both my ajax and my normal loading of a page.
Currently I am using:
console.info(req.get('Content-Type')); //undefined.
Here is the node code I am using
getFixtures: function (req, res) {
var passData = {}
console.info(req.get('Content-Type'));
passData.params = req.params;
leagues(app).getLeagues(passData)
.then(filterBarFixtures)
.then(function () {
res.render('games', {
title: 'Fixtures and Results',
passData: passData
})
});
}
app.get('/fixtures/', controllers.getFixtures);
2 way of loading the same controller
Open a browser and navigate to /fixtures
or
$.ajax({
method: "GET",
url: "/fixtures"
})
You would need to either set a header in the client request to look for in the server, or perhaps a search/query parameter
However, as you are using jQuery you don't need to worry
jQuery $.ajax uses XMLHttpRequest, which sets X-Requested-With=XMLHttpRequest request header
Additionally, if the request is for JSON (using $.ajax with appropriate settings or $.getJSON), jQuery usually sets Accept:application/json, text/javascript, etc
note, I've said "usually" to cover my butt in case in some strange browser this doesn't happen :p
Your comment regarding
beforeSend: function(request) { request.setRequestHeader("ajax",true); }
Is probably the safest option, as that header is guaranteed to be present, so that's the header to look for on the server side.
There are a lot of answers all around the web how to prevent jQuery AJAX requests from being cached. This is not what I'm trying to do.
I need the AJAX request to be returned from the cache based on condition in my code. That is, when the request is issued during page load, it is completely ok to return cached response (in fact that is the intention). But when the user clicks a button, I need the same request to be refreshed from the server.
I know that I can do this by setting cache: false option in jQuery, but this will just request the data with a different URL thus not refreshing the response in the cache and during the next page load the request with cache: true will return the obsolete data.
I tried adding a Cache-Control header to the request but that does not have effect at least in IE10.
$.ajax({
url: Configuration.ApiRootUri + "Notifications",
type: "GET",
headers: { 'Cache-Control': refreshCache ? 'no-cache' : 'private' },
success: function(data) {}
});
Is it possible at all to force the browser to refresh a cached resource from script?
(note: rewritten after discussion in the comments)
A solution would be to store the response from the server in the localstorage and load it at page load if it does exists.
This avoid completely the request made to the server at start and act like a cache, but in the browser.
Here's a pseudo-algo example :
function loadRequest(){
Call Ajax request
On success, store the result in the localstorage, call updateHtml(result);
}
function updateHtml(data) {
Update the specific html (list, view, etc) with the data
}
$('#mybutton').on ('click', loadRequest);
$(function() {
Check if the data in the localstorage exists
if exists, call updateHtml(localstorage.value);
else call loadRequest
});
That's it!
How can I set a custom field in POST header on submit a form?
It cannot be done - AFAIK.
However you may use for example jquery (although you can do it with plain javascript) to serialize the form and send (using AJAX) while adding your custom header.
Look at the jquery serialize which changes an HTML FORM into form-url-encoded values ready for POST.
UPDATE
My suggestion is to include either
a hidden form element
a query string parameter
Set a cookie value on the page, and then read it back server side.
You won't be able to set a specific header, but the value will be accessible in the headers section and not the content body.
From FormData documention:
XMLHttpRequest Level 2 adds support for the new FormData interface. FormData objects provide a way to easily construct a set of key/value pairs representing form fields and their values, which can then be easily sent using the XMLHttpRequest send() method.
With an XMLHttpRequest you can set the custom headers and then do the POST.
In fact a better way to do it to save a cookie on the client side. Then the cookie is automatically sent with every page header for that particular domain.
In node-js, you can set up and use cookies with cookie-parser.
an example:
res.cookie('token', "xyz....", { httpOnly: true });
Now you can access this :
app.get('/',function(req, res){
var token = req.cookies.token
});
Note that httpOnly:true ensures that the cookie is usually not accessible manually or through javascript and only browser can access it.
If you want to send some headers or security tokens with a form post, and not through ajax, in most situation this can be considered a secure way. Although make sure that the data is sent over secure protocol /ssl if you are storing some sensitive user related info which is usually the case.
Here is what I did in pub/jade
extends layout
block content
script(src="/jquery/dist/jquery.js")
script.
function doThePost() {
var jqXHR = $.ajax({
type:'post'
, url:<blabla>
, headers: {
'x-custom1': 'blabla'
, 'x-custom2': 'blabla'
, 'content-type': 'application/json'
}
, data: {
'id': 123456, blabla
}
})
.done(function(data, status, req) { console.log("done", data, status, req); })
.fail(function(req, status, err) { console.log("fail", req, status, err); });
}
h1= title
button(onclick='doThePost()') Click
You could use $.ajax to avoid the natural behaviour of <form method="POST">.
You could, for example, add an event to the submission button and treat the POST request as AJAX.
If you are using JQuery with Form plugin, you can use:
$('#myForm').ajaxSubmit({
headers: {
"foo": "bar"
}
});
Source: https://stackoverflow.com/a/31955515/9469069
To add into every ajax request, I have answered it here:
https://stackoverflow.com/a/58964440/1909708
To add into particular ajax requests, this' how I implemented:
var token_value = $("meta[name='_csrf']").attr("content");
var token_header = $("meta[name='_csrf_header']").attr("content");
$.ajax("some-endpoint.do", {
method: "POST",
beforeSend: function(xhr) {
xhr.setRequestHeader(token_header, token_value);
},
data: {form_field: $("#form_field").val()},
success: doSomethingFunction,
dataType: "json"
});
You must add the meta elements in the JSP, e.g.
<html>
<head>
<!-- default header name is X-CSRF-TOKEN -->
<meta name="_csrf_header" content="${_csrf.headerName}"/>
<meta name="_csrf" content="${_csrf.token}"/>
To add to a form submission (synchronous) request, I have answered it here:
https://stackoverflow.com/a/58965526/1909708
I know that you can't, when using an XMLHttpRequest, intercept a redirect or prevent it, as the browser will transparently follow it, but is it possible to either
A. Determine whether a request redirected, or
B. Determine where it redirected to? (assuming that the response gives no hints)
Example code:
$.post("/my-url-that-redirects/", {},
function(response, statusCode, xmlHttpRequest){
//Somehow grab the location it redirected to
}
);
In my case, firebug will first show a POST to the url, then a GET to the redirected url. Can that GET location be captured?
1) Use different status code than 301 (2**) (if request by ajax) and handle redirection on client side:
var STATUS = {
REDIRECT: 280
};
$.post('/redirected', {}, function(response, status, request) {
if (status == STATUS.REDIRECT) {
// you need to return the redirect url
location.href = response.redirectUrl;
} else {
$('#content').html(request.responseText);
}
});
2) DO NOT REDIRECT:
I use that in "redirect pattern" = redirecting after post request (you don't want to allow user to refresh the post request, etc..)
With ajax request, this is not necessary, so when the post request is ajax, I do forward instead (just forward to different controller - depends on your server-side framework, or what you are using...). POST requests are not cached by browsers.
Actually, I don't know what's the reason you need that, so this might not be so useful for you. This is helpful when server returns different responses for ajax requests than common requests, because when browser redirect ajax request, the redirected request is not XMLHttpRequest...
[updated]
You can access headers (of redirected request) like that:
$.post('redirected', {}, function(r, s, req) {
req.getAllResponseHeaders();
req.getResponseHeader('Location');
});
There should be 'Location' header, but it depends on the server, which headers are sent back...
After 4 years now it's possible to find the last redirect location using responseURL from XHR instance in Chrome 42+ (Opera 29+) and Firefox 39+ but it's not available in IE, Edge or safari yet.