Avoid caching JS, CSS files page after each deployment - javascript

We are using ASP.Net. But in the front end, we are using HTML pages. So server side code could not used there.
By implementing like this "login.js?s09809808098" we can resolve this. But we can't manually edit this on every pages before each deployment. Is there any method to edit the html pages in server side when a page is requested. Or any other method to resolve this issue?

You can try adding expiration headers and dont cache headers to fix this problem.
You can also create a center repo for static URL assests and when your repo return the URL append a software version like login.js?v1 this way you will get new version with every release. also define the version number as a property in the repo class.
public static class URLRepo {
public string AppVersion = "1";
public string GetURL (enumURLName urls)
{
switch(enumURLName)
{
case enumURLName.LoginJS
return "Login.JS?v" + AppVersion;
break;
}
}
}
public enum enumURLName
{
LoginJS,
LoginCSS
}

Related

How to access elements under `shadow-root` at 'chrome://downloads' using jquery and selenium?

I am trying to get the name of the last downloaded file in my selenium javascript application.
I have my selenium driver navigating to the chrome downloads page using: driver.get('chrome://downloads'); , but when I get there, selenium is not able to find ANY elements on the download page.
The chrome downloads page 'chrome://downloads' has a bunch of shadow-root elements that I don't know how to get underneath in order to access the id's that I want. How do I access identifiers beneath shadow-root items?
I want to get $("#file-link") as shown here:
But when I use jquery to find it, everything returns null (probably because it's behind shadow-root)
Here's a big picture of all the information I have including showing that "#file-link" totally exists:
The code I am using to wait for the element to exist is the same that I use for all elements in my application, so I think this is already working:
driver.wait(until.elementLocated(By.id('downloads-manager')), 120000).then(function(){
console.log("#downloads-manager shows");
driver.findElement(By.id('downloads-manager')).then(function(dwMan){
//How do I "open" #shadow-root now? :(
});
});
Here is my version information:
Chromium v54.0.2840.71
Node v6.5.0
ChromeDriver v2.27.440175
selenium-webdriver v3.4.0
Similar Question
Selenium webdriver can't find elements at chrome://downloads (This is the same problem I am having but in python)
Links
Selenium Javascript API: https://seleniumhq.github.io/selenium/docs/api/javascript/
The $ from your example is not a shorthand for JQuery.
It's function overridden by the page to locate an element by id only:
function $(id){var el=document.getElementById(id);return el?assertInstanceof(el,HTMLElement):null}
To select through the shadow DOM, you need to use the '/deep/' combinator.
So to get all the links in the download page:
document.querySelectorAll("downloads-manager /deep/ downloads-item /deep/ [id=file-link]")
And with Selenium:
By.css("downloads-manager /deep/ downloads-item /deep/ [id=file-link]")
Why not check the downloads folder directly? I do this for downloading Excel files. I first clear the downloads folder, click the button to download the file, wait ~5 sec (varies by file size, internet speed, etc.), and then looking in the folder for a "*.xlsx" file. This also has the benefit of working with any browser.
C# Examples:
/// <summary>
/// Deletes the contents of the current user's "Downloads" folder
/// </summary>
public static void DeleteDownloads()
{
// Get the default downloads folder for the current user
string downloadFolderPath = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) + "\\Downloads";
// Delete all existing files
DirectoryInfo di = new DirectoryInfo(directoryPath);
foreach (FileInfo file in di.GetFiles())
{
file.Delete();
}
foreach (DirectoryInfo dir in di.GetDirectories())
{
dir.Delete(true);
}
}
/// <summary>
/// Looks for a file with the given extension (Example: "*.xlsx") in the current user's "Download" folder.
/// </summary>
/// <returns>Empty string if files are found</returns>
public static string LocateDownloadedFile(string fileExtension)
{
// Get the default downloads folder for the current user
string downloadFolderPath = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) + "\\Downloads";
DirectoryInfo di = new DirectoryInfo(downloadFolderPath);
FileInfo[] filesFound = di.GetFiles(fileExtension);
if (filesFound.Length == 0)
{
return "No files present";
}
else
{
return "";
}
}
And then in my Test I can Assert.IsEmpty(LocateDownloadedFile); This way if the assert fails, the error message if printed.
Expected: String.Empty.
Actual: No files present.

Call a Java Function using Browser's Client Side JavaScript

Good morning!
I have been working on a client side browser based app using JavaScript that (all of a sudden) needs the capability to save and load files locally.
The saved files are plain text (.txt) files.
I have managed to get JavaScript to read existing text files. However, I am unable to find reliable information on how to create and edit the contents of these files.
Based on what I see online, I am under the impression that you can't do this with JavaScript alone.
I found out from another source that the best way to do this is outsource the file writing/editing to a Java file and let Java do the work.
I found a code snippet and tweaked it around a bit, but it is not working and I seem to be at a loss:
JAVASCRIPT
<!Doctype html>
<html>
<OBJECT ID="Test" height=0 width=0
CLASSID="CLSID:18F79884-E141-49E4-AB97-99FF47F71C9E" CODEBASE="JavaApplication2/src/TestJava.java" VIEWASTEXT>
</OBJECT>
<script language="Javascript">
var Installed;
Installed = false;
try
{
if (Test==null)
Installed = false;
else
Installed = true;
}
catch (e)
{
Installed = false;
}
alert ("Installed :- " + Installed);
TestStr = Test.SendStr("Basil");
alert (TestStr);
</script>
</html>
JAVA
import javax.swing.*;
public class TestJava {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
}
public String SendStr(String lStr)
{
return lStr + "!!!";
}
}
If someone could point me in the right direction or even just explain why this isn't working, I would appreciate it.
I believe the sandbox issue prevents all browsers from performing any and all local file writing, without an enormous amount of working around the access restrictions. It is easier to write files remotely on the server than to write them locally to the client. This is true across all browsers.
So while it may be possible to perform the load function, you cannot perform the 'save' function on the local machine.

How to add different Javascript in development and production wicket

I have a wicket application in which I have added the javascript files within the markup html:
<script src="script/jquery.min.js" type="text/javascript"></script>
My javascript files are not placed beside my .java or .html files, they are in different location in the server as can be seen on previous script declaration.
My question is: Is it possible to add these javascript files depending on the application mode? I.E. if the application is in development mode, load one javascript file, if it is in production load this other one.
Thanks!
PS: the idea is to load "min" version on production but the extended files on development so debugging becomes posible
NOTE: Watching different answers here I re-state: the problem is not finding when the wicket app is in development or deployment mode, I know that, but is about how to change html markup or adding different JavaScript resources
extendig the answer of #rotsch you can do it in wicket 1.5 with :
#Override
public void renderHead(IHeaderResponse response) {
if(DEVELOPMENT)
response.renderString("<script type=\"text/javascript\" src=\"url1\"></script>");
else
response.renderString("<script type=\"text/javascript\" src=\"url2\"></script>");
}
https://cwiki.apache.org/WICKET/migration-to-wicket-15.html#MigrationtoWicket1.5-RemovedHeaderContributorandfriends.
You can find out in which mode you are with the following code:
RuntimeConfigurationType.DEPLOYMENT.equals(getApplication().getConfigurationType())
or
RuntimeConfigurationType.DEVELOPMENT.equals(getApplication().getConfigurationType())
I use this directory layout:
resources
|---JQueryResource.java
|---jquery-1.6.4.js
|---jquery-1.6.4.min.js
With this class:
public class JQueryResource {
/**
* Must be called in a RequestCycle.
*
* #return Url for the jQuery library.
*/
public static String getURL() {
if (Application.get().usesDevelopmentConfig()) {
Url url =
RequestCycle.get().mapUrlFor(
new PackageResourceReference(JQueryResource.class, "jquery-1.6.4.js"),
null);
return url.toString();
} else {
Url url =
RequestCycle.get().mapUrlFor(
new PackageResourceReference(JQueryResource.class,
"jquery-1.6.4.min.js"), null);
return url.toString();
}
}
}
This is how I add the resource to my page.
#Override
public void renderHead(IHeaderResponse a_response) {
a_response.renderJavaScriptReference(JQueryResource.getURL());
}
You could use pack:tag to compress all your resources: http://sourceforge.net/projects/packtag/
In your web.xml/.properties file you can specify whether to pack it or not depending on your production mode.
I set a property in a properties file with I add to the path when starting the VM.
Then I do a if else similar to the PHP answer.

How to version MVC JavaScript includes [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
force browsers to get latest js and css files in asp.net application
I'm working with someone else's code, so I don't know the whole picture, and I don't even know MVC that well, but here's the problem...
In Site.Master there's a
<%= Html.IncludeJs("ProductPartial")%>
which produces this line in the final mark-up
<script type="text/javascript" src="/Scripts/release/ProductPartial.js"></script>
I made some changes in the JS file, but the old one is obviously cached by the browser, so the changes won't show up until the user refreshes. The usual workaround is to add a version tag at the end of the script source path, but I'm not sure how to do that in this case.
Any suggestions?
Why not write your own Html helper extension method, and make it output the version number of your application assembly? Something along these lines should do the trick:
public static MvcHtmlString IncludeVersionedJs(this HtmlHelper helper, string filename)
{
var version = Assembly.GetExecutingAssembly().GetName().Version;
return MvcHtmlString.Create(filename + "?v=" + version);
}
You can then increment the version number of the assembly whenever you release a new version to your users, and their caches will be invalidated across the application.
I solved this by tacking a last modified timestamp as a query parameter to the scripts.
I did this with an extension method, and using it in my CSHTML files. Note: this implementation caches the timestamp for 1 minute so we don't thrash the disk quite so much.
Here is the extension method:
public static class JavascriptExtension {
public static MvcHtmlString IncludeVersionedJs(this HtmlHelper helper, string filename) {
string version = GetVersion(helper, filename);
return MvcHtmlString.Create("<script type='text/javascript' src='" + filename + version + "'></script>");
}
private static string GetVersion(this HtmlHelper helper, string filename)
{
var context = helper.ViewContext.RequestContext.HttpContext;
if (context.Cache[filename] == null) {
var physicalPath = context.Server.MapPath(filename);
var version = "?v=" +
new System.IO.FileInfo(physicalPath).LastWriteTime
.ToString("yyyyMMddhhmmss");
context.Cache.Add(physicalPath, version, null,
DateTime.Now.AddMinutes(1), TimeSpan.Zero,
CacheItemPriority.Normal, null);
context.Cache[physicalPath] = version;
return version;
}
else {
return context.Cache[filename] as string;
}
}
And then in the CSHTML page:
#Html.IncludeVersionedJs("/MyJavascriptFile.js")
In the rendered HTML, this appears as:
<script type='text/javascript' src='/MyJavascriptFile.ks?20111129120000'></script>
Here are some links already on this topic:
Why do some websites access specific versions of a CSS or JavaScript file using GET parameters?
force browsers to get latest js and css files in asp.net application
Your version strategy really isn't important. As long as the file name is different, the browser will be forced to get the new script. So even this would work:
<%= Html.IncludeJs("ProductPartialv1")%>
ProductPartialv1.js
I have been using this technique for important JavaScript and CSS changes (CSS is also cached by the browser) - so I update the template to use the newer version and I'm safe in the knowledge that if the new HTML is used, so is the new script and CSS file.
It is "in action" on http://www.the-mag.me.uk/ - where I just increment a numeric suffix on the files.
It turns out IncludeJs is a helper method for automatically including compressed JS files when in release mode: LINK.
So I just have to modify that method a bit to include a version number. Sorry about the confusion.

Load file after page is complete without redirecting

I am trying to do pretty much the same, as is for example on Sourceforge. After a user creates some data, I generate a file and I want it to be offered to him after a page load. However, I know almost nothing about javascript and simple copy-paste of
<script type="text/javascript">
var download_url = "http://downloads.sourceforge.net/sourceforge/itextsharp/itextsharp-4.1.2-dll.zip?use_mirror=dfn";
function downloadURL() {
if (download_url.length != 0 && !jQuery.browser.msie) {
window.location.href = download_url;
}
}
jQuery(window).load(downloadURL);
</script>
is not enough. It is important for the user to download the file, so how to do that?
A question related to the previous is - where to store the file i created? Once while using the asp.net development server and then on the real IIS server? And how should this address look? When I tried
setTimeout("window.location.href='file://localhost/C:/Downloads/file.pdf'", 2000);
I was getting nothing, with HTTP an error of unknown address.
See Haack's DownloadResult example. It explains (I think) exactly what you're truing to do. Except you would provide the timeout call with your download action url.
you're asking the user's browser to look for a file on their own computer... that you're trying to save there.
you could use something like:
window.location.href='http://www.yourServer.com/generatePDF.asp?whatever=whatever'
where http://www.yourServer.com/generatePDF.asp?whatever=whatever is what is generating the pdf file for the user
On the server, you have to set the content disposition in the response header to "Attachment" as described in these answers.
If you do that, the download will not affect the page that is currently displayed in the browser. So, if you initiate a request in Javascript that gets an attachment, the browser will leave the page alone, and the user will see a message box with the Open/Save/Cancel question.
You can create your own PdfResult which extends ActionResult like this:
public class PdfResult : ActionResult
{
public byte[] Content { get; set; }
public string FileName { get; set; }
public override void ExecuteResult(ControllerContext context)
{
var response = context.HttpContext.Response;
response.AddHeader("content-disposition", "attachment; filename=" + this.FileName);
response.AddHeader("content-length", this.Content.Length.ToString());
response.ContentType = "application/pdf";
using (MemoryStream memoryStream = new MemoryStream(this.Content))
{
memoryStream.WriteTo(response.OutputStream);
}
response.End();
}
Then in your action you can simply return the file as follows:
public ActionResult Pdf(string param1...)
{
var content = GeneratePdf(); //etc
var fileName = AssignFileName();
return new PdfResult { Content = content, FileName = fileName + ".pdf" };
}
A couple of different things. First, since you are using MVC, create an action that actually generates the file and returns it as a FileResult. The file can be an actual file on the server, but it can also be generated dynamically -- say in a MemoryStream -- and the FileResult created from that. Set the content to application/octet-stream or the actual file type if it's not one that will render in the browser via a plugin. Second, don't generate the file in the action that renders the page, but rather call the action that generates the FileResult from that page using the technique you've referenced (though it looks like they are doing something different for IE). If the MIME type is not one that can be rendered it will be downloaded.
public ActionResult GenerateFile( string value, int other )
{
MemoryStream file = new MemoryStream();
...
return File( file, "application/octet-stream" );
}

Categories

Resources