Let's say I have a bunch of scripts on my server, which are used in my app.
So, my <head> contains a bunch of
<script src="http://myServer.com/myScript.js"></script>
If I am developing on localhost & don't have net access, I would like to reference those as a bunch of
<script src="http://localhost/myScript.js"></script> or, even,
<script src="myScript.js"></script>
I am very new to JS, is there a standard way to switch between two possible servers for the script file? Google is not my friend on this matter.
You could just dynamically load the script and add it to the document, based on whether you're accessing the page from localhost or not, as such:
<script>
var script = document.createElement("script");
if (/localhost/.test(document.location.hostname)) {
script.setAttribute("src", "./myScript.js");
} else {
script.setAttribute("src", "http://www.myServer.com/myScript.js");
}
document.body.appendChild(script);
</script>
In situations where I'd like to be able to continue development while offline on a webapp that has resources pulled from CDNs, I've used fallbacks.
For example, for jQuery:
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script type="text/javascript">
if(!window.jQuery) {
document.write('<script src="./js/jquery.min.js"><\/script>');
console.error('jQuery from CDN not available - reverting to local copy');
}
</script>
Or for BootstrapJS:
<script type="text/javascript" src="//netdna.bootstrapcdn.com/bootstrap/3.0.2/js/bootstrap.min.js"></script>
<script type="text/javascript">
if(!(typeof $().modal == 'function')) {
document.write('<script src="./js/bootstrap.min.js"><\/script>');
console.error('Bootstrap JS from CDN not available - reverting to local copy');
}
</script>
Or for FontAwesome:
<link type="text/css" rel="stylesheet" href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.min.css" />
...
<span class="fa hide" id="faChecker"></span>
<script type="text/javascript">
if($('#faChecker').css('fontFamily') !== 'FontAwesome') {
$('<link type="text/css" rel="stylesheet" href="./css/font-awesome.min.css" \/>').appendTo('head');
console.error('FontAwesome CSS from CDN not available - reverting to local copy');
}
</script>
Similarly, you can make use of some variable that myScript.js would set and if it's not set, use the local fallback version.
This has the added benefit of helping prevent your site from malfunctioning if a CDN goes down.
Related
I'm trying to run the ConvNetJS example through the Cloud9 online IDE. The script included works when it is inside the HTML, but not when I link it as follows:
<html>
<head>
<title>minimal demo</title>
<!-- CSS goes here -->
<style>
body {
background-color: #FFF; /* example... */
}
</style>
<!-- http://jquery.com/ -->
<script type="text/javascript" src="https://code.jquery.com/jquery-latest.min.js"></script>
<!-- http://getbootstrap.com/ -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<!-- import convnetjs library -->
<script src="//cs.stanford.edu/people/karpathy/convnetjs/build/convnet-min.js"></script>
<!-- app's own JavaScript -->
<!--script type="text/javscript" src="../static/script.js"></script-->
</head>
<body>
<div id="egdiv"></div>
</body>
</html>
with the javascript inside script.js:
function periodic() {
var d = document.getElementById('egdiv');
d.innerHTML = 'Random number: ' + Math.random();
};
var net; // declared outside -> global variable in window scope
$(function start() {
// this gets executed on startup
net = new convnetjs.Net();
// example of running something every 1 second
setInterval(periodic, 1000);
});
When I run the application through the IDE I get this warning through the console: Mixed Content: The page at 'https://ide50-stephenwist.cs50.io/' was loaded over HTTPS, but requested an insecure script 'http://cs.stanford.edu/people/karpathy/convnetjs/build/convnet-min.js'. This content should also be served over HTTPS.
How do I get around this? I am using chrome and letting it run 'insecure scripts'. Thanks for giving this a read, here's a puppy
You just can't load unsecured content without having this warning.
The only thing you can do when you have some unsecured external content to load is to copy that content and save it on your secured domain.
This way, you are able to run it from a secured address (yours).
NOW, cs.stanford.edu is a secured website.
So just add the https: in front of //cs.stanford.edu/people/karpathy/convnetjs/build/convnet-min.js and there will be no warning.
How about try to add https: in front of your cdn //cs.stanford.edu/people/karpathy/convnetjs/build/convnet-min.js.
Perheps something like https://cs.stanford.edu/people/karpathy/convnetjs/build/convnet-min.js should prevent Chrome warning?
I have a website that I want to work online and offline. I want to decrease load time, so I minified the slow loading scripts. It didn't work enough. Locally, some of the scripts are taking 4-6 seconds to load.
I know that linking scripts externally speeds it up drastically. I have tried it and it works. But some of the users will not have internet access. Is there a way to link a group of scripts to an external site, and locally if they do not have internet access?
<script src="js/jquery-1.9.1.min.js" type="text/javascript"></script>
<script src="js/jquery.dataTables.min.js" type="text/javascript"></script>
<script src="ui/jquery-ui.min.js" type="text/javascript"></script>
You can do something similar to this answer. Basically, the idea is that you attempt to load the Internet based script for jQuery. Afterward, you do a normal script where you check if jQuery === undefined. If it does, you want to load the local copy.
Basically, an example of what you want to do:
<script src="[jQueryURL]" type="text/javascript"></script>
<script src="[dataTablesURL]" type="text/javascript"></script>
<script src="[jQueryUIURL]" type="text/javascript"></script>
<script type="text/javascript">
if(jQuery === undefined) {
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "js/jquery-1.9.1.min.js";
document.getElementsByTagName('head')[0].appendChild(script);
//repeat for other two scripts here
}
</script>
What will happen is that it will attempt to load the scripts in question, and afterward it will check if jQuery is defined. If it's not, that means the scripts didn't load, so you want to load the local versions and append them to your header.
Ensure that the script declares a global variable you can test for. Then generate a local script loading element if the external script fails to load (which you can determine by testing for that variable).
<script src="http://example.com/example.js"></script>
<script>
if !(window.Example) {
document.write('<script src="../scripts/example.js"><\/script>');
}
</script>
<script type="text/javascript">
if(navigator.onLine)
{
alert("Connected");
}
else
{
alert("Not Connected");
}
</script>
First Check if internet connection exist then load external file other wise load internal file
I have this block of javascript in a Rails app, with turbo-link enabled:
<script type="text/javascript" language="javascript" src="//cdn.datatables.net/1.10.0/js/jquery.dataTables.min.js"></script>
<script type="text/javascript" language="javascript" src="//cdn.datatables.net/plug-ins/be7019ee387/integration/bootstrap/3/dataTables.bootstrap.js"></script>
<script type="text/javascript" charset="utf-8">
var ready = function() {
setTimeout(function() {
$('#table-products').dataTable();
}, 100);
};
$(document).on('ready, page:change', ready);
</script>
Usually, I get the error that the .dataTable() function is undefined, and a refresh can solve the problem. However, refresh is not always pleasant, so I added the setTimeout for 100ms to wait for the js from CDN to load.
So far I don't see any issue in my dev environment, but I am afraid that if there is a slow client, the js won't finish loading within 100ms.
I wonder if there would be a better way to solve this, like checking if the two js files have been loaded, similar to $(document).ready for DOM.
Thanks!
There's actually a gem for this. It's really easy to use and comes with bootstrap styling options. This is more elegant than what you have because it doesn't rely on CDNs and instead leverages the Rails asset pipeline.
Try
<head>
<script type="text/javascript" language="javascript" src="//code.jquery.com/jquery-1.10.2.min.js"></script>
<script type="text/javascript" language="javascript" src="//cdn.datatables.net/1.10.0/js/jquery.dataTables.min.js"></script>
<script type="text/javascript" language="javascript" src="//cdn.datatables.net/plug-ins/be7019ee387/integration/bootstrap/3/dataTables.bootstrap.js"></script>
<script type="text/javascript" charset="utf-8">
$.holdReady(true);
var s = setInterval(function() {
if ($.fn.hasOwnProperty("DataTable")
&& typeof $.fn.DataTable === "function") {
$.holdReady(false);
clearInterval(s);
};
}, 1);
$(document).ready(function() {
$("#table-products").dataTable();
});
</script>
</head>
jsfiddle http://jsfiddle.net/guest271314/RZVRL/
See https://api.jquery.com/jQuery.holdReady/
The most elegant way I can find is to move all the cdn links to the layout page in the , so that all the libraries will be loaded and cached for the entire user experience.
So lets say you're implementing a website that uses jQuery HEAVILY. You could put some code like
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
and import it from some repository. If you're developing it without internet you could download the source and store it somewhere locally, then access it with some script like
<script src="js/jquery-1.10.2.min.js"></script>
But is there a simple way to have both? Such as if you can reach the repository use that, but if you can't use the local copy.
Check for a variable in the first script. If it is not found, use document.write to create the second script tag. Here is an example for jQuery I found here:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script>!window.jQuery && document.write('<script src="js/jquery-1.7.1.min.js"><\/script>')</script>
The fail-safe way of referencing scripts on a CDN is to link to the local copy only if the CDN has failed for any reason.
The way to do this is simply to check if anything within the script has executed. For jQuery this is simply checking whether jQuery exists:
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.18/jquery-ui.min.js"></script>
<script type="text/javascript">
if (!window.jQuery) document.write('<script type="text/javascript" src="/path/to/jquery-ver.sion.min.js"><\/script>');
</script>
Personally I have never had a script fail due to a CDN being offline, however I have had periods of internet outage. With scripts set up with a proper fallback, I've been able to continue local development as the pages still work without needing to connect to a CDN.
You can add resources dynamically if required one is not available. for eg:
<html>
<head>
<script type="text/javascript" src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
<script type="text/javascript">
if( typeof $ != "function")
{
var head= document.getElementsByTagName('head')[0];
var script= document.createElement('script');
script.type= 'text/javascript';
script.src= 'js/jquery-1.10.2.min.js';
head.appendChild(script);
}
</script>
</head>
<body>
</body>
</html>
Though JQuery hosted on Google CDN should be safe enough, the codes below can be used as a fallback with requireJS.
requirejs.config({
enforceDefine: true,
paths: {
jquery: [
'//ajax.googleapis.com/ajax/libs/jqueryui/1.8.18/jquery-ui.min.js',
'js/jquery-ui.min.js'
]
}
});
require(['jquery'], function ($) {
});
I am trying to update an old cometd javascript wrapper and test client (was 1.3.x) that I have to the newer comet 2.5.1 javascript implementation. I have all of the dependencies and the browser can find them all, yet I am getting errors in Firebug's console (see below)
The head of my HTML is as below:
<head>
<title>CometD Tester</title>
<link rel="stylesheet" type="text/css"href="style/style.css" />
<script type="text/javascript" src="org/cometd/Cometd.js"></script>
<script type="text/javascript" src="org/cometd/AckExtension.js"></script>
<script type="text/javascript" src="org/cometd/ReloadExtension.js"></script>
<script type="text/javascript" src="jquery/jquery-1.9.0.js"></script>
<script type="text/javascript" src="jquery/jquery.cookie.js"></script>
<script type="text/javascript" src="jquery/jquery.cometd.js"></script>
<script type="text/javascript" src="jquery/jquery.cometd-reload.js"></script>
<script type="text/javascript" src="js/myCometd.js"></script>
</head>
All of these are found by the browser. Looking at Cometd.js I see the following:
org.cometd.Cometd = function(name)
{
....
}
So is that not defining org? Note that none of the errors in the Console are from Cometd.js. Otherwise I see no other definition of "org.cometd". I would really appreciate it if anyone can help me out. I am using Tomcat 7 and below is the dir structure:
Thanks.
UPDATE - Further testing
I reduced the header to:
<head>
<title>CometD Tester</title>
<link rel="stylesheet" type="text/css"href="style/style.css" />
<script type="text/javascript" src="org/cometd/Cometd.js"></script>
</head>
And removed ALL JS from the index.html. The only JS now included is the Cometd.js from the comet.org. There is still the same error... coming from the very first line in that script:
org.cometd.Cometd = function(name)
Not sure what I have missed here.
EDIT - Add jquery.cometd-reload.js
This is the contents of the file. It looks like it is "re-binding" functionality from the cometd library to use the jquery one instead (?). I'm not up to speed enough in JS to debug this (I'm a C++ dev really).
(function($)
{
function bind(org_cometd, cookie, ReloadExtension, cometd)
{
// Remap cometd COOKIE functions to jquery cookie functions
// Avoid to set to undefined if the jquery cookie plugin is not present
if (cookie)
{
org_cometd.COOKIE.set = cookie;
org_cometd.COOKIE.get = cookie;
}
var result = new ReloadExtension();
cometd.registerExtension('reload', result);
return result;
}
if (typeof define === 'function' && define.amd)
{
define(['org/cometd', 'jquery.cookie', 'org/cometd/ReloadExtension', 'jquery.cometd'], bind);
}
else
{
bind(org.cometd, $.cookie, org.cometd.ReloadExtension, $.cometd);
}
})(jQuery);
So the problem was that I misunderstood the project layout from the Comet.org site. I should have followed the direction posted at cometd primer for non-maven setups a lot more closely. Basically when you are setting up the project you download the distribution, and then you need to take the code from the war files bundled inside the tarball.
SO, once you have extracted the tarball...
Take the org folder from cometd-javascript-common-2.5.1.war (located in \cometd-2.5.1\cometd-javascript\jquery\target) or cometd-javascript-jquery-2.5.1.war (located in \cometd-2.5.1\cometd-javascript\common\target)
Take the jquery folder from cometd-javascript-jquery-2.5.1.war
The org namespace definition was in the file org/cometd.js which I did not have before, as I wrongly assumed that it had been replace by the org/cometd/Cometd.js file. The namespaces org and comet are defined as below starting on line 17 of that file:
// Namespaces for the cometd implementation
this.org = this.org || {};
org.cometd = {};
org.cometd.JSON = {};
The functions are working correctly now.
Try loading jQuery before any of the other JavaScript files -
<head>
<title>CometD Tester</title>
<link rel="stylesheet" type="text/css"href="style/style.css" />
<script type="text/javascript" src="jquery/jquery-1.9.0.js"></script> <!-- load first -->
<script type="text/javascript" src="org/cometd/Cometd.js"></script>
<script type="text/javascript" src="org/cometd/AckExtension.js"></script>
<script type="text/javascript" src="org/cometd/ReloadExtension.js"></script>
<script type="text/javascript" src="jquery/jquery.cookie.js"></script>
<script type="text/javascript" src="jquery/jquery.cometd.js"></script>
<script type="text/javascript" src="jquery/jquery.cometd-reload.js"></script>
<script type="text/javascript" src="js/myCometd.js"></script>
</head>