I have a large JSON blob I would like to have preloaded with my webpage. To do this, I have added <link rel="preload" as="fetch" href="/blob.json"> to my page. I also have a JS request to fetch the same blob.
This does not work, and the console reports:
[Warning] The resource blob.json was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it wasn't preloaded for nothing.
MDN claims that this can be fixed by adding crossorigin to the link tag. AFAICT, this is not true, and no combination or crossorigin attributes will actually make it work.
Using the copy-as-curl command from the developer console, it seems like there is no combination of link tag plus attributes that will issue the same request as a fetch/XHR call in JS.
I would love to be wrong about this.
Here is the working solution to preload fetch that works both in Chrome and Safari and supports cookies.
Unfortunately, it works only for the same domain requests.
First, do not specify crossorigin attribute for preload tag, this will ensure Safari will send request in no-cors mode and include cookies
<link rel="preload" as="fetch" href="/data.json">
Second, the fetch api request should also be done in no-cors mode and include credentials (cookies).
Pay attention that this request cannot have any custom headers (like Accept, Content-Type, etc), otherwise the browser won't be able to match this request with preloaded one.
fetch('/data.json', {
method: 'GET',
credentials: 'include',
mode: 'no-cors',
})
I have tried other combinations of crossorigin attribute value and fetch API configuration, but none of them worked for me in Safari (only in Chrome).
Here is what I have tried:
<link rel="preload" as="fetch" href="/data.json" crossorigin="anonymous">
<script>
fetch('/data.json', {
method: 'GET',
credentials: 'same-origin',
mode: 'cors',
})
</script>
The above works in Chrome, but not in Safari, because cookies are not sent by preload request in Safari.
<link rel="preload" as="fetch" href="/data.json" crossorigin="use-credentials">
<script>
fetch('/data.json', {
method: 'GET',
credentials: 'include',
mode: 'cors',
})
</script>
The above works in Chrome but not in Safari. Though cookies are sent by preload request, Safari is not able to match fetch with preload request probably because of the different cors mode.
Thanks to the discussion in this bug, I got fetch to work with preload in Chromium 67:
First, add crossorigin attribute to the preload link:
<link rel="preload" as="fetch" href="/blob.json" crossorigin="anonymous">
Second, add same-origin credentials to the fetch request:
fetch(url, {credentials: 'same-origin'}).then(response => {
console.log(response);
});
Alternatively, you can use XMLHttpRequest instead of fetch (with XHR you don't need to add anything to the request), but only if you're not going to use responseType = 'blob' - it won't work due to another bug.
It looks like this is a difference between Safari and Chrome. Safari posts the warning to console, but Chrome does not, so maybe adding crossorigin to the link element does solve the problem, but Safari has some kind of bug?
Related
The occurence seems to happen at completely random intervals
Accompanied by message in Chrome console: Resource interpreted as
Document but transferred with MIME type application/octet-stream:
"<url>"
It only happens when loaded from disk cache - if a cache refresh is
forced then it displays in the Chrome as expected
Currently the CSS file is hosted on sirv.com - this may or may not be
significant
Here is the HTML code used to load the CSS:
<link rel="stylesheet" href="<url>" media="all">
Remove media="all" and it will be solved <link> is itself used for loading.
The media attribute specifies what media/device the target resource is optimized for.
The default is always media="all" so you don't need to specify it again
I am working on a chrome extension, written in React, and attaches itself to the page using a shadow DOM element. Inside I am loading the extension's logo and a content stylesheet.
However, it was reported that the extension was not loading properly and have pinpointed that any resource from web_accessible_resources (e.g. chrome-extensions://...) were being unmounted from the page on certain sites (e.g. https://www.skechers.com/).
In a work-around we ended up serving the content from our CDN, which works fine. Still wondered if anyone knew why this didn't work on a few sites.
I also wrote code to see if it removes the stylesheet and then loads the CDN version, just to test it out.
const onStylesLoad = (loaded) => {
const sheet = loaded.target.sheet
setTimeout(() => {
if (!sheet.ownerNode) {
console.log('FALLBACK', sheet);
setFallback('https://cdn.***/themes/browserExtension/content.css');
}
}, 1000);
}
// And later in the render...
<link rel='stylesheet' type='text/css' onLoad={onStylesLoad} href={browser.runtime.getURL('content.css')} />
{fallback && <link rel='stylesheet' type='text/css' href={fallback} />}
The extensions stylesheet does load, but then is immediately unmounted, which is how I am able to detect a moment later that the ownerNode is null (onLoad its attached to the link).
I am fine with the work-around, it just irks me that packaging any content is made moot, since we have too point it to a CDN regardless.
If you want to store the css files locally, rather than from a CDN, you could minify the css files, then store them as a string in your js files and insert them into the page by creating a style element on document ready. I guess they probably wouldn't be able to reference the local images though, but it seems you're not able to anyway
As the title states, I am getting the following three warnings in Chrome (latest version):
1) A preload for 'https://use.fontawesome.com/releases/v5.8.2/css/all.css' is found, but is not used due to an integrity mismatch
2) The resource https://use.fontawesome.com/releases/v5.8.2/css/all.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate as value and it is preloaded intentionally
3) A preload for 'https://use.fontawesome.com/releases/v5.8.2/css/all.css' is found, but is not used because the request credentials mode does not match. Consider taking a look at crossorigin attribute.
While I understand that these are not errors, do they represent a bigger issue or can it be safely ignored? I recently switched to https but to be honest, it might have been showing this in the chrome inspect window before this (I only saw it because I was checking the SSL post installation.
I have Googled parts of these warnings but havn't found anything. I used the "pasted into your head" method of adding Font Awesome, like this:
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.2/css/all.css" integrity="sha384-oS3vJWv+0UjzBfQzYUhtDYW+Pj2yciDJxpsK1OYPAYjqT085Qq/1cq5FLXAZQ7Ay" crossorigin="anonymous">
Would appreciate a little feedback, thanks in advance!
This is due to your use of crossorigin="anonymous", and you can safely ignore these warnings, but they will be visible to your users, so it is best to correct the problems.
To do so, you'll want to ensure that your font is preloaded with the rel preload (with rel="preload"), and an as attribute declaring it as a font (with as="font").
This would look like:
<link rel="preload" as="font" href="https://use.fontawesome.com/releases/v5.8.2/css/all.css" integrity="sha384-oS3vJWv+0UjzBfQzYUhtDYW+Pj2yciDJxpsK1OYPAYjqT085Qq/1cq5FLXAZQ7Ay" crossorigin="anonymous">
I am learning to develop xhtml, css web pages. Often I am doing changes in CSS but it do not reflect on page because of browser cacheing and if I manually clear cahceing it shows latest code effects. Is there a thing I can put in code to make browker not to cache stuff ? Any advice please
You can append a random query parameter to the stylesheet url (for example via javascript or server side code).
It will not change the css file that is being loaded, but it will prevent caching, because the browser detects a different url and will not load the cached stylesheet.
<link rel="stylesheet" type="text/css" href="http://mysite/style.css?id=1234">
You can create class with GetVersion method which will return your application version (or for example build number or build date).
For asp.net application in markup you can then specify something like this:
<script src="Scripts/some.js?version=<%= Common.GetVersion%>" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="~/styles/Style.css?version=<%= Common.GetVersion%>" />
This will force browser to reload files because part of URL to static files will be changed every build (or at least every version).
With no catching:
Put changeable strings at the end of css path, as bellow:
<link rel="stylesheet" type="text/css" href="style.css?2016-12-3:10 13 30"/>
Refresh when version changes:
<link rel="stylesheet" type="text/css" href="style.css?v=1.1.0"/>
If you're using Chrome as your development browser, there are 2 options:
1) When you hold the reload page button down for a second, a menu will appear and offer the possibility to do a hard page reload.
2) In the Inspector settings, you can force the browser to never cache files.
I think it's easier, faster and less trouble to handle this issue by disabling caching on the browser than in the server configuration.
This can be done through a .htaccess file. Place this code in a file named .htaccess at the root of your website:
<filesMatch "\.(html|htm|js|css)$">
FileETag None
<ifModule mod_headers.c>
Header unset ETag
Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
Header set Pragma "no-cache"
Header set Expires "Wed, 11 Jan 1984 05:00:00 GMT"
</ifModule>
</filesMatch>
instead of writing <link> tag using html just use php code. inside <link> tag at the end use php mt_rand() function which will produce a random number and thus your stylesheet will never get cached.
<?php
echo "<link rel='stylesheet' type='text/css' href='style.css?'".mt_rand().">";
?>
Since the ASP.net tag is also included in the question, I'd like to expand on Maxim Kornilov's answer (https://stackoverflow.com/a/12992813/903783) with how I used his idea of making the URLs webapp-build-specific on ASP.net MVC (his example was in ASP/ASP.net WebForms syntax instead of MVC's and Razor Pages' newer Razor syntax):
1) Added to the webapp's main class (was called MvcApplication) in Global.asax.cs
#region Versioning
public static string Version => typeof(MvcApplication).Assembly.GetName().Version.ToString(); //note: syntax requires C# version >=6
public static DateTime LastUpdated => File.GetLastWriteTime(typeof(MvcApplication).Assembly.Location);
#endregion
the someProperty => someReadOnlyExpression syntax is just shorthand for someProperty { get { return ... ;} } possible since C# 6
2) in its Content/_Layout.cshtml file I used to have the following to show build number and build datetime (based on the webapp's main assembly) on the page footer:
Version #ViewContext.Controller.GetType().Assembly.GetName().Version (#string.Format("{0:yyyy/MM/dd-HH:mm:ss}", #File.GetLastWriteTime(ViewContext.Controller.GetType().Assembly.Location)))
which I changed to the simpler:
Version #somewebappname.MvcApplication.Version (#string.Format("{0:yyyy/MM/dd-HH:mm:ss}", somewebappname.MvcApplication.LastUpdated))
3) it was loading the CSS via hardcoded link in _Layout.cshtml (still refactoring it) which I changed to:
<link href='#Url.Content("~/Content/Site.css?version=" + somewebappname.MvcApplication.Version)' rel="stylesheet" type="text/css" />
so if one right-clicks in the webpage and they do view source they see:
<link href='/Content/Site.css?version=2.1.5435.22633' rel="stylesheet" type="text/css" />
that is the CSS url is version specific thanks to the dummy parameter version
If a random number was used instead it would fetch the CSS at every page load which is usually undesired, especially if you are already pushing a new webapp build instead of individual page changes to the web server (so that you do have access to a build number that you can inject into URLs).
Note that to achieve auto-incrementing of build number, at Properties/AssemblyInfo.cs I have (see How to have an auto incrementing version number (Visual Studio)?):
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.*")]
//[assembly: AssemblyFileVersion("1.0.*")] //don't use boh AssemblyVersion and AssemblyFileVersion with auto-increment
You can use random version id in your link. for example use this:
<link href=<%="'mystyle.css?version="+ DateTime.Now.ToString("yyyyMMddhhmmss") +"'"%> rel="stylesheet" type="text/css"/>
where myStyle.css is stylesheet file and DateTime.Now.ToString("yyyyMMddhhmmss") function used for generate random different version id.
By using this random version id,browser forced to reload your css.
If you are in Google Chrome simply press CTRL + F5 to force said refresh. The CSS will be updated to how it is on your local machine or server. You can also use a .htaccess file, but that is more of a permanent solution to a possibly temporary problem. CSS caching is good for faster page loading, so I do not recommend disabling it entirely.
Press F12 on the chrome to open the developer tool
Then right-click on the reload button - Click (Clear Cache and Hard Reload)
I'm using Less in JS mode (less.js) the following way:
<link rel="stylesheet/less" href="assets/styles/less/bootstrap.less" media="all">
<script src="assets/scripts/libs/less-1.1.5.min.js"></script>
And after some page views, it stops processing the styles and gives a "cached" version. To make it re-parse the styles I have to clear browser cookies. Does anybody knows why is this? Is there any option to make it re-parse on every page view?
Thanks a lot!
UPDATE: Reviewing some of the library code, seems that it uses localStorage to store the stylesheets as a cache. It bases on file's last modified time to update that cache but for some reason it's not working properly because it's not taking my changes...
I just found a issue in GitHub for this. Quoting myself:
This happens to me also in 1.1.5. The script uses localStorage to store the stylesheets. Clearing your browser cache won't work. You must clear it's cookies (logging off all your accounts, %!#^#%) or doing localStorage.clear(). I use this before loading less.js (not using localStorage myself):
<script> /* Provisory for dev environment: */ localStorage.clear(); </script>
When going to production you just compile the stylesheets to .css
Nice find with the localStorage. The quickest solution, then, is to open up your browser's console and run the following command:
localStorage.clear();
Then refresh and you are set.
You can use the following to disable the localStorage cache:
<script>var less=less||{};less.env='development';</script>
<script src="path_to_less.js"></script>
The reason it caches it is because it takes time to generate the css files and that time can add up to a bad user experience if you have a lot of code to compile.
you could put this in your html documents:
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">
<META HTTP-EQUIV="Expires" CONTENT="-1">
But that would disable caching of all resources not just your less files.
A better way of doing this would be by passing noCache=1 into the url to clear the browser localStorage when you are developing in less files then it sets a cookie to remember to clear it each time and then you could put noCache=0 to unset the cookie, this way the end user doesn't end up having their localStorage deleted when using your site and you can just leave it in.
$(document).ready(function () {<br>
if(window.location.href.indexOf("noCache=1") > -1) {<br>
$.cookie('noCache', '1', { expires: 1, path: '/' });<br>
localStorage.clear();<br>
}<br>
if(window.location.href.indexOf("noCache=0") > -1) {<br>
$.cookie('noCache', '0', { expires: 1, path: '/' });<br>
}<br>
if ($.cookie('noCache') == '1'){<br>
alert ("disabled Cache");<br>
localStorage.clear();<br>
}<br>
});<br>
<br>
you will need jquery cookie plugin for this to work
you can also add a unique parameter to prevent caching, like this for example if you are using php:
<link rel="stylesheet/less" href="assets/styles/less/bootstrap.less?v=<?= uniqid() ?>" media="all">