Javascript status code for a webpage [duplicate] - javascript

Is there any way to get the http status of the current web page from javascript?
Spent some time searching on the web, but no luck at all... Seems like it's not possible, but wanted to check with Stack Overflow for maybe some fancy workaround.
(Providing it from the server as part of the response body is not acceptable, the status is supposed to be only available via the http header)

This is not in any way possible, sorry.

Yes You can
Simply request the same page, i.e. URI, using the XMLHttpRequest. Suppose that your page on /stop.php in stop.php you may do something like:
<script>
function xhrRequest(){
console.log(this.status);
// Do some logic here.
}
function getReq(url){
var oReq = new XMLHttpRequest();
oReq.addEventListener("load", xhrRequest);
oReq.open("GET", url);
oReq.send();
}
getReq("/stop.php");
</script>
Checkout this DEMO
🕯 Note:
You have to note that, it is a copy of the page not the page itself.
I, already, have used this solution on a page in which the server may
generate Forbidden HTTP status code when the request is come from
unauthorized IP address, so the condition here is very simple and
there is no much difference between the original and the copy page
that you have simulate its visit.

As a one liner:
fetch(location.href).then(response => console.log(response.status));
This is asynchronous, if you need a synchronous solution use XMLHttpRequest (as in the other answer) together with async: false or use async/await which feels synchronous, but is still asynchronous under the hood.
Alternatively
An approach without an extra call would need to include the status code in the page on the server side (e.g. in a meta tag), then read it on the client side via JavaScript.
Java + Thymeleaf:
<meta name="statuscode" th:content="${#response.status}">
PHP (unverified):
<meta name="statuscode" content="<?php echo http_response_code() ?>">

It is not beautiful, but you can use:
t = jQuery.get(location.href)
.success(function () { console.log(t.status) })
.error(function() { console.log(t.status) });
That When Eric says, this solution will make a new request from the same paga, and not show status of current request.

you can only check status of page loading
try:var x = document.readyState;
The result of x could be:
One of five values:
uninitialized - Has not started loading yet
loading - Is loading
loaded - Has been loaded
interactive - Has loaded enough and the user can interact with it
complete - Fully loaded

Related

does window.location.reload(true) clear cache of asynchronous loaded resources? [duplicate]

How do I clear a browsers cache with JavaScript?
We deployed the latest JavaScript code but we are unable to get the latest JavaScript code.
Editorial Note: This question is semi-duplicated in the following places, and the answer in the first of the following questions is probably the best. This accepted answer is no longer the ideal solution.
How to force browser to reload cached CSS/JS files?
How can I force clients to refresh JavaScript files?
Dynamically reload local Javascript source / json data
Update: See location.reload() has no parameter for background on this nonstandard parameter and how Firefox is likely the only modern browser with support.
You can call window.location.reload(true) to reload the current page. It will ignore any cached items and retrieve new copies of the page, css, images, JavaScript, etc from the server. This doesn't clear the whole cache, but has the effect of clearing the cache for the page you are on.
However, your best strategy is to version the path or filename as mentioned in various other answers. In addition, see Revving Filenames: don’t use querystring for reasons not to use ?v=n as your versioning scheme.
You can't clear the cache with javascript.
A common way is to append the revision number or last updated timestamp to the file, like this:
myscript.123.js
or
myscript.js?updated=1234567890
Try changing the JavaScript file's src? From this:
<script language="JavaScript" src="js/myscript.js"></script>
To this:
<script language="JavaScript" src="js/myscript.js?n=1"></script>
This method should force your browser to load a new copy of the JS file.
Other than caching every hour, or every week, you may cache according to file data.
Example (in PHP):
<script src="js/my_script.js?v=<?=md5_file('js/my_script.js')?>"></script>
or even use file modification time:
<script src="js/my_script.js?v=<?=filemtime('js/my_script.js')?>"></script>
You can also force the code to be reloaded every hour, like this, in PHP :
<?php
echo '<script language="JavaScript" src="js/myscript.js?token='.date('YmdH').'">';
?>
or
<script type="text/javascript" src="js/myscript.js?v=<?php echo date('YmdHis'); ?>"></script>
window.location.reload(true) seems to have been deprecated by the HTML5 standard. One way to do this without using query strings is to use the Clear-Site-Data header, which seems to being standardized.
put this at the end of your template :
var scripts = document.getElementsByTagName('script');
var torefreshs = ['myscript.js', 'myscript2.js'] ; // list of js to be refresh
var key = 1; // change this key every time you want force a refresh
for(var i=0;i<scripts.length;i++){
for(var j=0;j<torefreshs.length;j++){
if(scripts[i].src && (scripts[i].src.indexOf(torefreshs[j]) > -1)){
new_src = scripts[i].src.replace(torefreshs[j],torefreshs[j] + 'k=' + key );
scripts[i].src = new_src; // change src in order to refresh js
}
}
}
try using this
<script language="JavaScript" src="js/myscript.js"></script>
To this:
<script language="JavaScript" src="js/myscript.js?n=1"></script>
Here's a snippet of what I'm using for my latest project.
From the controller:
if ( IS_DEV ) {
$this->view->cacheBust = microtime(true);
} else {
$this->view->cacheBust = file_exists($versionFile)
// The version file exists, encode it
? urlencode( file_get_contents($versionFile) )
// Use today's year and week number to still have caching and busting
: date("YW");
}
From the view:
<script type="text/javascript" src="/javascript/somefile.js?v=<?= $this->cacheBust; ?>"></script>
<link rel="stylesheet" type="text/css" href="/css/layout.css?v=<?= $this->cacheBust; ?>">
Our publishing process generates a file with the revision number of the current build. This works by URL encoding that file and using that as a cache buster. As a fail-over, if that file doesn't exist, the year and week number are used so that caching still works, and it will be refreshed at least once a week.
Also, this provides cache busting for every page load while in the development environment so that developers don't have to worry with clearing the cache for any resources (javascript, css, ajax calls, etc).
or you can just read js file by server with file_get_contets and then put in echo in the header the js contents
Maybe "clearing cache" is not as easy as it should be. Instead of clearing cache on my browsers, I realized that "touching" the file will actually change the date of the source file cached on the server (Tested on Edge, Chrome and Firefox) and most browsers will automatically download the most current fresh copy of whats on your server (code, graphics any multimedia too). I suggest you just copy the most current scripts on the server and "do the touch thing" solution before your program runs, so it will change the date of all your problem files to a most current date and time, then it downloads a fresh copy to your browser:
<?php
touch('/www/control/file1.js');
touch('/www/control/file2.js');
touch('/www/control/file2.js');
?>
...the rest of your program...
It took me some time to resolve this issue (as many browsers act differently to different commands, but they all check time of files and compare to your downloaded copy in your browser, if different date and time, will do the refresh), If you can't go the supposed right way, there is always another usable and better solution to it. Best Regards and happy camping.
I had some troubles with the code suggested by yboussard. The inner j loop didn't work. Here is the modified code that I use with success.
function reloadScripts(toRefreshList/* list of js to be refresh */, key /* change this key every time you want force a refresh */) {
var scripts = document.getElementsByTagName('script');
for(var i = 0; i < scripts.length; i++) {
var aScript = scripts[i];
for(var j = 0; j < toRefreshList.length; j++) {
var toRefresh = toRefreshList[j];
if(aScript.src && (aScript.src.indexOf(toRefresh) > -1)) {
new_src = aScript.src.replace(toRefresh, toRefresh + '?k=' + key);
// console.log('Force refresh on cached script files. From: ' + aScript.src + ' to ' + new_src)
aScript.src = new_src;
}
}
}
}
If you are using php can do:
<script src="js/myscript.js?rev=<?php echo time();?>"
type="text/javascript"></script>
Please do not give incorrect information.
Cache api is a diferent type of cache from http cache
HTTP cache is fired when the server sends the correct headers, you can't access with javasvipt.
Cache api in the other hand is fired when you want, it is usefull when working with service worker so you can intersect request and answer it from this type of cache
see:ilustration 1 ilustration 2 course
You could use these techiques to have always a fresh content on your users:
Use location.reload(true) this does not work for me, so I wouldn't recomend it.
Use Cache api in order to save into the cache and intersect the
request with service worker, be carefull with this one because
if the server has sent the cache headers for the files you want
to refresh, the browser will answer from the HTTP cache first, and if it does not find it, then it will go to the network, so you could end up with and old file
Change the url from you stactics files, my recomendation is you should name it with the change of your files content, I use md5 and then convert it to string and url friendly, and the md5 will change with the content of the file, there you can freely send HTTP cache headers long enough
I would recomend the third one see
You can also disable browser caching with meta HTML tags just put html tags in the head section to avoid the web page to be cached while you are coding/testing and when you are done you can remove the meta tags.
(in the head section)
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0"/>
Refresh your page after pasting this in the head and should refresh the new javascript code too.
This link will give you other options if you need them
http://cristian.sulea.net/blog/disable-browser-caching-with-meta-html-tags/
or you can just create a button like so
<button type="button" onclick="location.reload(true)">Refresh</button>
it refreshes and avoid caching but it will be there on your page till you finish testing, then you can take it off. Fist option is best I thing.
I tend to version my framework then apply the version number to script and style paths
<cfset fw.version = '001' />
<script src="/scripts/#fw.version#/foo.js"/>
Cache.delete() can be used for new chrome, firefox and opera.
I found a solution to this problem recently. In my case, I was trying to update an html element using javascript; I had been using XHR to update text based on data retrieved from a GET request. Although the XHR request happened frequently, the cached HTML data remained frustratingly the same.
Recently, I discovered a cache busting method in the fetch api. The fetch api replaces XHR, and it is super simple to use. Here's an example:
async function updateHTMLElement(t) {
let res = await fetch(url, {cache: "no-store"});
if(res.ok){
let myTxt = await res.text();
document.getElementById('myElement').innerHTML = myTxt;
}
}
Notice that {cache: "no-store"} argument? This causes the browser to bust the cache for that element, so that new data gets loaded properly. My goodness, this was a godsend for me. I hope this is helpful for you, too.
Tangentially, to bust the cache for an image that gets updated on the server side, but keeps the same src attribute, the simplest and oldest method is to simply use Date.now(), and append that number as a url variable to the src attribute for that image. This works reliably for images, but not for HTML elements. But between these two techniques, you can update any info you need to now :-)
Most of the right answers are already mentioned in this topic. However I want to add link to the one article which is the best one I was able to read.
https://www.fastly.com/blog/clearing-cache-browser
As far as I can see the most suitable solution is:
POST in an iframe. Next is a small subtract from the suggested post:
=============
const ifr = document.createElement('iframe');
ifr.name = ifr.id = 'ifr_'+Date.now();
document.body.appendChild(ifr);
const form = document.createElement('form');
form.method = "POST";
form.target = ifr.name;
form.action = ‘/thing/stuck/in/cache’;
document.body.appendChild(form);
form.submit();
There’s a few obvious side effects: this will create a browser history entry, and is subject to the same issues of non-caching of the response. But it escapes the preflight requirements that exist for fetch, and since it’s a navigation, browsers that split caches will be clearing the right one.
This one almost nails it. Firefox will hold on to the stuck object for cross-origin resources but only for subsequent fetches. Every browser will invalidate the navigation cache for the object, both for same and cross origin resources.
==============================
We tried many things but that one works pretty well. The only issue is there you need to be able to bring this script somehow to end user page so you are able to reset cache. We were lucky in our particular case.
window.parent.caches.delete("call")
close and open the browser after executing the code in console.
Cause browser cache same link, you should add a random number end of the url.
new Date().getTime() generate a different number.
Just add new Date().getTime() end of link as like
call
'https://stackoverflow.com/questions.php?' + new Date().getTime()
Output: https://stackoverflow.com/questions.php?1571737901173
I've solved this issue by using
ETag
Etags are similar to fingerprints, and if the resource at a given URL changes, a new Etag value must be generated. A comparison of them can determine whether two representations of a resource are the same.
Ref: https://developer.mozilla.org/en-US/docs/Web/API/Cache/delete
Cache.delete()
Method
Syntax:
cache.delete(request, {options}).then(function(found) {
// your cache entry has been deleted if found
});

simple javascript/ajax call - does not return status

The following code produces nothing on the html page, it seems to break down on 'status':
var get_json_file = new XMLHttpRequest();
get_json_file.open("GET", "/Users/files/Documents/time.json", true);
**document.write(get_json_file.status);**
keep in mind, that I am on a Mac, so there is no C: drive....however, this line of code does work fine:
document.write(get_json_file.readyState);
I just want to know that I was able to successfully find my json file. Perhaps, I should ask, what should I be looking for to achieve what I want ?
Another basic question about AJAX. I suggest you to read the MDN article about using XMLHttpRequest. You can't access the 'status' property until it is ready, and you haven't even called the 'send()' method, which performs the actual request. You can't have a status without making an HTTP request first. Learn how AJAX works before trying to use it. Explaining it all would be too long and this is not the place.
You can only get the status when the ajax has finished. That is, when the page was loaded, or a 404 was returned.
Because you're trying to call status straight after the request was sent (or not sent, read the P.S), you're getting nothing.
You need to make an async call, to check that status only when the request finishes:
get_json_file.onreadystatechange = function (){
if (get_json_file.readyState==4 && get_json_file.status==200)
{
alert('success');
}
}
read more at http://www.w3schools.com/ajax/ajax_xmlhttprequest_onreadystatechange.asp
P.S as noted by #Oscar, you're missing the send().
If you want to try a synchronous approach, which would stop the code from running until a response is returned, you can try:
var get_json_file = new XMLHttpRequest();
get_json_file.open("GET", "/Users/files/Documents/time.json", false);
//notice we set async to false (developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest)
get_json_file.send(); //will wait for a response
document.write(get_json_file.status);
//(Credit: orginial asker)
Because of security issues you are not allowed to send requests to files on the local system, but what you could do is look into the fileReader API. (more info here)
<sidenote>
The reason that the readyState works and not status is because by defualt
readyState has a value of 0 and status has no value so it would be undefined.
</sidenote>
in my ubuntu, the path will be prefixed with file:///
i think your json file path should have file:///Users/files/Documents/time.json, because mac and ubuntu based on unix
and then you can check ajax status using #TastySpaceApple answer
if you using google chrome, don't forget to launch it with -–allow-file-access-from-files command, because google chrome not load local file by default due to security reason

JavaScript: don't unload document until HttpRequest is complete

I need to make sure that when someone reloads or closes my page, their progress is saved. To save progress, I do a POST via XMLHttpRequest(), sending the data to server.
I'm triggering this saveData() function inside a window.onbeforeunload event.
The problem is, that saveData() does some calculations, and then calls a sendData(content) to finally actually POST the data.
And if the data I'm processing&sending is large (>100kB), the window seems to close before all the data gets through to the server. (I'm sending an image, and some times I only get half of it on the other side)
The http request is synchronous, xhr.open("POST", url, false), but that doesn't seem to cut it.
So my question is, how can I keep the onbeforeunload function from terminating, UNTIL xhr.readyState == 4? How do I make it wait for that event?
Oh, and setTimeout() will not work. The window will close before the "Time" comes.
This won't work:
if (!jQuery) {
setTimeout(attachCode, 100);
return;
} else {
// continue and close
}
Thanks for any insight!
PS: this shouldn't be "bad practice" since it only takes a few of seconds and I don't want the user to have to save manually. Also, saving while he works (as in, before he closes window), would slow down the app so I can't do that.
[EDIT] As a temporary measure, I resorted to using this trick to auto save the data if the user decides to stay on the page. However, I'd really like to not need to use any alert messages. :(
Disallowing the browser to do it's normal behaviour is normally a bad idea. And with onbeforeunload you can't pause the unload, you can only let the user know, that he/she is leaving the page and then let them decide, whether or not to leave the page - and thus the data unsaved.
So i your case, i would suggest an draft autosave, like you see in Google documents + a warning when the user leaves the page with unsaved data.
Actually you can slow down the browser before unloading. The problem lies in how JS handles the ajax requests.
Quite a while ago I had to do a quick and dirty hack about almost the same thing - logging some stuff, before navigating. The only way I found to do it is to wait for the return value of the XHR request.
Even though it's synchronous, the execution of the code forks in background and doesn't actually block the browser. You have to get the return value to be able to halt the script to upload the data.
Mind that I used jQuery for this, but it applies to native JS (I think.. :))
/* some code above */
var request = {
async:false,
cache: false,
url: this.serviceURL,
type: 'POST',
data: {...},
success: function(data) {}
};
try {
var asd = $j.ajax(request); // do the request and wait
}
catch (e) {}
/* some code below */
I hope this helps.

Problem with making a simple JS XmlHttpRequest call

Edit: Maybe I made the question more complex than it should. My questions is this: How do you make API calls to a server from JS.
I have to create a very simple client that makes GET and POST calls to our server and parses the returned XML. I am writing this in JavaScript, problem is I don't know how to program in JS (started to look into this just this morning)!
As n initial test, I am trying to ping to the Twitter API, here's the function that gets called when user enters the URL http://api.twitter.com/1/users/lookup.xml and hits the submit button:
function doRequest() {
var req_url, req_type, body;
req_url = document.getElementById('server_url').value;
req_type = document.getElementById('request_type').value;
alert("Connecting to url: " + req_url + " with HTTP method: " + req_type);
req = new XMLHttpRequest();
req.open(req_type, req_url, false, "username", "passwd");// synchronous conn
req.onreadystatechange=function() {
if (req.readyState == 4) {
alert(req.status);
}
}
req.send(null);
}
When I run this on FF, I get a
Access to restricted URI denied" code: "1012
error on Firebug. Stuff I googled suggested that this was a FF-specific problem so I switched to Chrome. Over there, the second alert comes up, but displays 0 as HTTP status code, which I found weird.
Can anyone spot what the problem is? People say this stuff is easier to use with JQuery but learning that on top of JS syntax is a bit too much now.
For security reasons, you cannot use AJAX to request a file from a different domain.
Since your Javascript isn't running on http://api.twitter.com, it cannot request files from http://api.twitter.com.
Instead, you can write server-side code on your domain to send you the file.

How can I take common large chunks of oft-reused HTML source code?

A slew of pages I've written for one of my web projects share some 144 identical lines of code, reproduced in each file. If I update one of those lines, I have to go back through ALL of the pages that share the code and update for each page. Is there a straightforward way to include HTML from a separate file?
And for bonus points, since so many pages use this code, it would be nice not to have to reload it for each page. Is there an easy way to store it in the browser's cache or only load the "content" section of the pages while leaving the rest of the page static?
Fountains of Thanks for any wisdom on this.
Mike
To include HTML from a separate file, use SSI (Server-Side Includes). This requires SSI support to be installed on the server, however.
You would write something like this in your files:
<!--#include file="included.html" -->
and that would include the file included.html when the page is accessed.
To load only the content of each page, use the XMLHTTPRequest object from JavaScript:
function LoadContent(url)
{
if (typeof(XMLHttpRequest) == "undefined")
{
try
{
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
}
catch(e)
{
try
{
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
catch(e)
{
// fallback for browsers without XMLHttpRequest
window.location.href = "no-ajax.php?url="+escape(url);
return;
}
}
}
else
{
xmlhttp = new XMLHttpRequest();
}
xmlhttp.open("GET", url, false); // this request will be synchronous (will pause the script)
xmlhttp.send();
if(xmlhttp.status > 399) // 1xx, 2xx and 3xx status codes are not errors
{
// put error handling here
}
document.getElementById("content").innerHTML = xmlhttp.responseText;
}
If we're assuming that you're talking straight html pages, with no server code (asp.net, php, or server side include ability), then in order to do both the including and the caching, you're going to need to use an iframe.
Each of your pages that duplicate the 144 lines of content should replace it with an iframe like so:
<iframe src="pagewithcontent.html"></iframe>
pagewithcontent.html would obviously be where you move the content to. The browser will cache the page appropriately, so that each parent page will simply get the shared content without making another request.
There's an article here that goes into great depth about html includes, and some javascript methods of doing it. I would strongly recommend against the javascript methods.
My answer reflects the assumption that you can't do anything on the server side. However, by far the best solution is to do so if you can.

Categories