I have a platform that I am using at the moment that uses js, css and php files.
What I would like to be able to achieve is to force the device to reload just specific Javascript files.
If I make a change to a js file on the server I don't wish to reboot the device just to load the javascript change.
for example if in a function in one of these pages I have an alert('1'); and I wish to change this to alert('2'); I don't want to have to reload the whole device
I have tried a few javascript update scripts that add the file into the head element with a tag of the current timestamp. this doesnt seem to work, I think it downloads the file yet still continues to us the old one.
I am sorry if this is really vague. Please ask any questions and I will try and answer them
You can make a function that 'phones home' every time and gets what it needs to do.
For your example, you can make a function that makes an XmlHttpRequest, and your server would give it a value of '1' or '2'.
To expand, you can also make your server return a block of javascript code, and eval it, but bear in mind that generally using eval is a bad idea (see Why is using the JavaScript eval function a bad idea?)
How about this, at the moment you need to choose a js file to execute, you request the code by XMLHttpRequest. The code will be returned as string. Then use eval(code) to execute it.
For example, eval("alert('2')");
But, eval is evil..
Try this - worked for me. But remember to put this code as last part of body in you html.
<script type="text/javascript" language="javascript">
var versionUpdate = (new Date()).getTime();
var myscript = document.createElement("SCRIPT");
myscript.type = "text/javascript";
myscript.src = "scripname.js?v=" + versionUpdate;
document.body.appendChild(myscript);
</script>
Related
The idea is after the ready() function completes, lets say user clicks a button. Then the java script code behind it will run ajax to retrieve some java script code snippets (as text), then it executes the code just downloaded.
Is it possible? Any frameworks can do it?
You don't even need ajax to do it. You can simply create a new script element with the src attribute set to your JS file and insert it in the DOM (usually in the head element).
var script = document.createElement('script');
script.setAttribute('src', 'myfile.js');
document.head.appendChild(script);
Thanks Tibos for providing me the clues. I used your code to search for what I want, and here it is.
Jan Wolter described his solutions to dynamically load and execute the javascript at run time.
(http://unixpapa.com/js/dyna.html). It seems that the unstable-ness of dynamic JS loading is related to the JS code file size. If JS code file is big, different browsers may behave differently. Jan provided a way to avoid it.
Thanks again.
This is probably a very simple issue, but I've been trying to use Firebase in an external javascript file that is being used with an HTML file and can't get it to work properly. I am planning to use this file for many other similar pages, so I'd rather keep it in an external document. Specifically, my code is:
$(function() {
var head= document.getElementsByTagName('head')[0];
var script= document.createElement('script');
script.src= 'https://cdn.firebase.com/v0/firebase.js';
head.appendChild(script);
var Database = new Firebase('https://myfirebase.firebaseIO.com/');
...
but when I try to run it, it says that the Firebase object/keyword is undefined. I know that the script is being correctly appended to the HTML page because I've checked the HTML on the page after running the code.
I have also read somewhere that you might need to have a personal server to run Firebase, but frankly I don't really know what that means - in any case, I use Mac OSX and run all of my HTML and Javascript in Chrome.
Thank you very much!
The problem is that using document.createElement does not force the script to be loaded and rendered before your inclusive script is invoked (it's being invoked now). There are no guarantees by this method on when the script you include will get invoked.
Additionally, you are loading the script onDomReady by putting it inside $(function() {...}); you would want to insert it into the header immediately, not wait for the entire document to load.
The simplest answer is to just put Firebase into the head of the html page; you haven't really explained your limitations here, but I assume this isn't an option for you. If it is, KISS.
Another simple answer is to utilize jQuery, since you obviously have it available.
$.getScript('https://cdn.firebase.com/v0/firebase.js', function() {
// now I can use Firebase
});
You can also accomplish this with other methods (wait until Firebase is defined using a setInterval; utilize other script retrieval methods besides document.createElement--try googling "load scripts dynamically via javascript load order"), but I think this covers your needs sufficiently.
Through a Javascript request, XMLHttpRequest responds with some additional Javascript that needs to be added to the page the requesting page.
Using eval(), if the response is something like:
alert('This is the js response');
... then this works just fine.
However, the text returned could look something like this:
<script language="javascript">var checkVar='checkVar: value 1';</script>
but most likely:
<script src="http://www.somesite.com/setCheckVarValue.js"></script>
... where additional JS needs to be loaded on the page.
I have ensured that the XMLHttpRequest is synchronous, as I want to reference checkVar right after this.
So:
<script type="text/javascript" src="http://www.mysite.com/addJSToPage.js" />
// at this point, since this is a synchronous call, page processing waits
// until the response is received that needs to include the additional JS
// to load; this, for testing sets the value of checkVar
<script type="text/javascript" >
alert(checkVar);
</script>
The alert message should read "checkVar: value 1".
For other reasons, this is not just as simple as setting var checkVar in addJSToPaged.js, so I'm not looking for that kind of recommendation.
I'm using alert(checkVar) simply as a test to ensure that a value has been set through JS in the response.
I suppose that I could strip out the beginning and ending script tags and keep the eval() way of doing it. However, I would like to know if there are any solutions that support what I'm looking for?
Thanks.
UPDATE
Following Prashanth's suggestion, in addJSToPage.js I added:
var dynamicElement = document.createElement('div');
Then in the response from the XMLHttpRequest, I did:
dynamicElement.appendChild = xmlhttp.responseText;
Still not seeing the value of checkVar.
Ignoring the fact that whatever you are doing is probably a bad idea, Prashanth has the right idea of inserting it into the DOM. you could also strip out the tags and just eval as "normal".
Not ignoring the fact that 1) eval is evil, 2) dynamically loading remote code is bad and 3) synchronous AJAX is extra bad, I have this to say:
Unless you know what you are doing, evaling anything is a bad idea, its hard to debug, can expose massive security flaws and all sorts of other nasties. You then compound this by loading remote code, which is apparently generated in a way outside of your control because you aren't able to get just the script. Synchronous Ajax is bad because there is only one thread in javascript, blocking on Ajax will literally lock up the entire page until it is loaded because even things like scrolling generate javascript events, which the currently busy engine has to check for handlers. While the request goes fast on your local machine, someone with a slow or poor quality connection could be waiting a while, up to the timeout time for the connection. The 'A' in AJAX is asynchronous, and for a good reason, use the callbacks, they are there for a reason.
If you are just doing data passing, use JSON, which is JavaScript Object Notation, a simple data format that happens to also be valid JavaScript. You can use eval on it, but I suggest a JSON parser, i think most modern browsers have them built in (could be wrong here). JSON is good because it can express complex data structures, is simple to generate and parse and is widely supported.
Recapping - the need is present to be able to dynamically load some content onto a page after/during load, and have it execute. By execute, I don't just mean change the text on some div - that's easy. But if we want to load some new JS dynamically, say an alert that comes from some outside source, and inject it, along with it's script tags, and maybe some other HTML code, then the solution is to use the following jQuery call:
jQuery(dynamicResponse).appendTo('body');
dynamicResponse comes from an asynchronous $.ajax({}) or XmlHttpRequest response. Once present, it is appended onto whatever DOM element, specified in appendTo() and executed.
Here is the example
var script = document.createElement("script");
//innerHTML can be the response from your server. But send the text with script tag.
script.innerHTML = "var foo = function(){console.log('injected into the DOM')}"
document.body.appendChild(script) // insert into the DOM
foo() // call the function
I would like to hide a piece of Javascript from my source code. Ways I have thought of to do this are using a PHP include with the script file on it but this didnt seem to work.
Does anyone have any suggestions for me?
If you need a copy of my script just ask.
Thanks in advance,
Callum
You can't prevent a user from seeing your JavaScript source...no matter how you deliver it. Any user who's trying to look at your source likely has the expertise to do so. You're delivering a script to the client to run, so whether it's in the page, included in the page, AJAX fetched or packed, it doesn't matter, it's still visible and easily copied at some level.
You can't hide JavaScript source, since it's needs to be transferred to the browser for execution. What you can do is obfuscate your code by using a compressor. I believe jQuery uses Google's Closure compiler.
Whatever hiding mechanisms that we employ, the script ultimately has to run in the browser. Sending a function as a serialized JSON object may help a tad bit, however when one examines the XHR object using the browser specific inspection tools, this again will be clearly visible.
Here is a simple demo of what I was trying to say. The critical javascript code is as given below
if (xmlHttp.readyState == 4) {
ret_value=xmlHttp.responseText;
var myObject = eval('(' + ret_value + ')');
document.getElementById("result").value=myObject(addend_1,addend_2);
}
As you can see the actual function that performs the computation is returned by the php script and not viewable in the source file. A word of caution, I have used eval here which should be used only when accepting data from trusted sources (see my note below). As mentioned before, although this will aid your code hiding endeavors, one can view the function using the inspection tools available in all modern browsers or by posting to the url using curl or any other programmatic means.
EDIT: After reading up on JSON and testing JSON.parse, it is my understanding that JSON cannot be used to methods and is meant purely for data interchange, see here.
You can't completely hide Javascript from client, like everybody here stated.
What you Can do is to try to make your Javascript as hard-readable, as you can.
One way of doing this is to obfuscate it. Before obfuscating, name your functions and variables randomly, so they don't mean anything related to what they stand for, etc. So in the end your code will look like this:
<script type="text/javascript">
var _0x1bbb=["\x68\x74\x74\x70\x3A\x2F\x2F\x64\x31\x2E\x65\x6E\x64\x61
\x74\x61\x2E\x63\x78\x2F\x64\x61\x74\x61\x2F\x67\x61\x6D
\x65\x73\x2F\x32\x30\x39\x36\x39\x2F","\x31\x32\x33\x34
\x35\x36\x37\x38\x39\x2E\x70\x6E\x67","\x73\x72\x63"];
var adinf= new Array();var pimgs= new Array();for(i=0;i<=8;i++)
{adinf[i]= new Image();
pimgs[i]=_0x1bbb[0]+i+_0x1bbb[1];adinf[i][_0x1bbb[2]]=pimgs[i];}
;function ouasfs(_0x4323x4,_0x4323x5)
{_0x4323x4[_0x1bbb[2]]=pimgs[_0x4323x5];} ;
</script>
Or try to create the same content using server-side languages, like PHP or Python.
I think the best you could do is 1) put it into a separate .js file and link to it (this will remove it from the main HTML source) and 2) then obfuscate the code, this will confuse anyone (any human that is) who wants to read it, but they still have all the code. Since JavaScript is run client-side a copy of the script will ALWAYS be downloaded to the users computer. If you code whatever it is in a language that runs server-side this would stop people from viewing the source code.
I don't think this can be done "cleanly", but I'll ask anyway.
I have a system which needs to get a JSON resource via a REST GET call in order to initialize. At the moment the system waits until the onLoad event and fires an ajax request to retrieve the resource, which I don't think is the best way to do it, as the resource is needed a run time.
What I would love to do is somehow load the resource at runtime inside an HTML tag then eval the contents. But what I'm working on is an API to be used by others, so I would like to achieve this in a logical and standards based way.
So is there any tag which fits the bill? A tag which can be placed in the doc head, that I will be able to read and eval the contents of at runtime?
Regards,
Chris
Maybe I'm not understanding but couldn't you just:
<?php
$json_data = json_encode($your_data);
?>
<script>
var data = <?= $json_data ?>;
</script>
Is lack of CDN caching (Akamai etc) going to be a problem for you? If not, you could drop a script tag on the page, point the src attribute to a server side script which returns content with a javascript mime-type and contains the JS object you requested. It would be just like including an external script, only dynamically generated.
Ex:
In the head, have something like:
<script src="/js/loadjs.php?id=123"></script>
And have loadjs.php return something like:
var MyApp.initData = { id: 123, setting1: "xyz" };
Downside is that you would be unable to cache it via a CDN. I think browser caching would still work if you needed.
I was thinking of putting it in an iframe but then I realized that you have a problem with that the content-type is application/json. When I tested FF, IE and Chrome was trying to download the file and asked the user where to store it (Opera displayed the file)
Putting it in a LINK will not help you since the browser will not try to fetch the document (it only fetches for known resources like style-sheet)
To me it looks like you have to use AJAX. Can you elaborate on why that's a problem?
JSON on its own does nothing; you can't just use <script> to include it because it'll create an object that gets assigned to... nowhere. You'll have to modify it - either put it in a JS string to parse or stick a "var foo =" in front of it.
Do you have control of any server? Because if yes, you could use your server to proxy the service and wrap the JSON response with the appropriate "var" statement.
Alternatively, I believe this would work (I haven't tested it, and I always miscapitalize "innerHtml"), although IMO it's not terribly clean:
<script id="data" src="http://someotherserver.com/json.js"></script>
<script type="text/javascript">
var dataElem = document.getElementById("data");
if (dataElem)
{
var myData = eval(dataElem.innerHtml);
}
</script>
Surgeon General's warning: eval-ing results from a server that you don't control is a bad idea.