I'm writing a javascript application. In my application I want to create my own cache management.
Now my question is: Is there any bottleneck in javascript (e.g. any event on window object) that we can handle and modify all server communications?
many tags in the page can request a resource from server e.g. img, link, script.
In other words I want a bottleneck in javascript that I can be notified that a resource is requested from server. Then I will look into my cache-system and will serve the resource either from my cache or by downloading the content from a generic HTTP handler on my server.
I know it's a bit strange requirement but because I believe javascript is very flexible I though this "bottleneck" may exist.
Thank you.
One way to lazy load resources is to set a common source (eg. 1.gif for images, x.txt for script/css) pointing at small, cacheable resources. Then set a data attribute on the element with the actual path to the content.
<img src="/1.gif" data-url="/images/puppies.png" class="onhold" />
Finally, on domready or document load you could do your logic to set the proper urls, replace dom element, etc. Using jQuery you'd do something like this -
jQuery(document).ready(function($){
$("img.onhold").each(function() {
var img = $(this),
url = img.data("url");
// any logic to update url based on cache, CDN, etc. here
img.attr("src", url);
});
});
Related
How can i cache javascript static files on www.foo.ru from www.abc.ru ?
I try load it by script tag (set src attribute), but when i go to www.abc.ru requests is sending again, cache is ignored. Does browser separate cache by origin or something else?
As Terry said in a comment, you can't do that directly. It used to be possible, but it was an information leak (http://malicious-site-example.com could see that it gets a really fast response to http://example.com/some-asset and use that information [probably in combination with other similar heuristics] to infer that you've been on http://example.com lately). So now, the cached response is only used for the origin that originally requested it — that is, effectively different origins have different caches.
Presumably you only want to do this on a pair of sites where you control both of them. In that case, you might use an iframe on foo.ru's page that directly loads a page from abc.ru that does the load. Then it's abc.ru that's doing the request, and it's cached such that it's connected to abc.ru, not foo.ru. You can hide the iframe by making it zero-height or off the page or similar.
In my webapp the user has the option to download a file containing some data, which they do by clicking on a button. For small amounts of data the file starts downloading pretty much immediately and that shows in the browser's download area. Which is good.
For large amounts of data it can take the server a substantial amount of time to calculate the data, even before we start downloading. This is not good. I want to indicate that the calculation is in progress. However I don't want to put a "busy" indicator on my UI, because the action does not block the UI - the user should be able to do other things while the file is being prepared.
A good solution from my point of view would be to start the download process before I have finished the calculation. We always know (or can quickly calculate) the first few hundred bytes of the file. Is there a mechanism where I can have the server respond to a download request with those few bytes, thus starting the download and making the file show up in the download area, and provide the rest of the file when I have finished calculating it? I'm aware that it will look like the download is stalled, and that's not a problem.
I can make a pretty good estimate of the file size very quickly. I would prefer not to have to use a third-party package to achieve this, unless it's a very simple one. We are using Angular but happy to code raw JS if needed.
To indicate that the link points to a download on the client, the easiest way is the download attribute on the link. The presence of the attribute tells the browser not to unload the current tab or create a new one; the value of the attribute is the suggested filename.
For the back-end part, after setting the correct response headers, just write the data to the output stream as it becomes available.
You asked for a general solution
1) First, at your HTML/JS you can prevent the UI from being blocked by setting you download target to any other WebPage, the preferred way for doing this is to set the target to an IFRAME:
<!-- your link must target the iframe "downloader-iframe" -->
<a src="../your-file-generator-api/some-args?a=more-args" target="downloader-iframe">Download</a>
<!-- you don't need the file to be shown -->
<iframe id="downloader-iframe" style="display: none"></iframe>
2) Second, at your back-end you'll have to use both Content-Disposition and Content-Length(optional) headers, be careful using the "length" one, if you miss calculate the fileSize it will not be downloaded. If you don't use Content-Length you'll not see the "downloading progress".
3) Third, at you'r back-end you have to make sure that you are writing your bytes directly at your response! that way your Browser and your Web-Server will know that the download is "in progress",
Example for Java:
Using ServletOutputStream to write very large files in a Java servlet without memory issues
Example for C#:
Writing MemoryStream to Response Object
HOW this 3 steps are built will be up to you, frameworks and libraries you are using, for example Dojo & JQuery have great IFRAME manipulation utilities, all thought you can do the coding by yourself, this is a JQuery sample:
Using jQuery and iFrame to Download a File
Also:
Adding a "busy" animation is ok! you just have to make sure that it's not blocking you'r UI, something like this:
How to secure the src path of the image when clicks on inspect element so that user should not get to know about the actual src path..please help me with the solution and it should be done with javascript only no other tags should be used.
You can convert image into base 64 data URIs for embedding images.
Use: http://websemantics.co.uk/online_tools/image_to_data_uri_convertor/
Code sample:
.sprite {
background-image:url(data:image/png;base64,iVBORw0KGgoAAAA... etc );
}
This is commonly done server-side, where you have an endpoint that serves the image file to you as bytes...
You can store the images in a private location on the server where IIS/<your favourite web server> doesn't have direct access to it, but only a web app, running on it, with the required privilege is authorized to do so.
Alternatively people also "store" the images in the database itself and load it directly from there.
In either case, the response which has to be sent back has to be a stream of bytes with the correct mime type.
Edit:
Here are a couple of links to get you started if you are into ASP.NET:
http://www.codeproject.com/Articles/34084/Generic-Image-Handler-Using-IHttpHandler
http://aspalliance.com/1322_Displaying_Images_in_ASPNET_Using_HttpHandlers.5 <- this sample actually does it from a database.
Don't let the choice of front-end framework (asp.net, php, django, etc) hinder you. Search for similar techniques in your framework of choice.
Edit:
Another way if you think html5 canvas is shown here: http://www.html5canvastutorials.com/tutorials/html5-canvas-images/
However you run into the same problem. Someone can view the image url if they can see the page source. You'll have to revert to the above approach eventually.
I want to proxy any possible request from a webpage using a websocket connection.
I've resolved this in ajax environment implementing a custom XHRHttpRequest.
For each link I remove the href destination (or set it to '#') and set an onclick event.
What can I do with the img tags?
Thanks
Nothing.
By the time your javascript executes, probably the IMG.src resolution is already in course.
You may add the src as data-src instead and then have some javascript code that either set the src attribute or get the image through the websocket.
But, why are you doing this? Request multiplexing is part of the HTTP2 spec. You should stick to common HTTP1.x practices for the moment like bundling CSS and JS, image sprite, image compression, leveraging HTTP caching, etc.. etc... Doing something like that you are going to get into big complexity.
I have a Javascript library I'm working on. It can be self-hosted or run from another server. The script makes a number of AJAX calls and the preferred method is making POST requests to the same host as the including page. To allow for cross-domain calls it also supports JSONP, but this limits the amount of data that can be sent (~2K to safely accommodate most modern browsers' URL length limits).
Obviously the user including the script knows where they're getting it from and could manually select JSONP as needed, but in the interest of simplifying things, I'd like to detect, within the script itself, whether the script was loaded from the same host as the page including it or not.
I'm able to grab the script element with jQuery but doing a $('script').attr('src') is only returning a relative path (e.g. "/js/my-script.js" not "http://hostname.com/js/my-script.js") even when it's being loaded from a different host.
Is this possible and if so, how would I go about it?
Thanks in advance.
Don't use JSONP, use CORS headers.
But if you really want to do JS check, use var t = $('script')[0].outerHTML.
Effect on my page:
[20:43:34.865] "<script src="http://www.google-analytics.com/ga.js" async="" type="text/javascript"></script>"
Checking location.host should do the trick.