Loading a JSON file in Firefox Addon Page Script, everything locally within the package - ajax

I have been developing a Firefox extension using the Addon SDK and need to load some data that is stored in the same package, as a separate file: "data.json". It needs to be loaded from a page script, i.e. "loader.js" which is included in the "panel.html" using the script src tags.
The structure is like this:
+data
panel.html
panel.js
loader.js
data.json
...
+lib
main.js
...
panel.html has:
<script type="text/javascript" src="loader.js"></script>
Initially we stored the data simply into a js file as "data.js" and included from the "panel.html" using script src tags and it worked without any problems. However when we submitted the add-on to the Mozilla Addon site, this was addressed as one of the issues to fix, saying that we need to use a non-executable format, such as a JSON file to make it more safe.
Now the problem seems like "loader.js" is not allowed to make a AJAX request to "data.json". (Using the JQuery $.ajax() call returns with no success, giving the error code 0) So the solution I have been thinking of is to load "data.json" from "main.js" using the SDK's request() function and somehow pass it to the "loader.js", the page script. But that seems to be complicated since, as far as I understand, the data needs to be first sent to a content script, and then from there to the page script. And this needs to be happen when the page script is loading! I am confused about this since I am not sure if I am missing a much more practical solution, or is it really something complicated what I am trying to do, simply loading local JSON data in the package into a local page script?

Here's an example on the Add-on Builder that explores and approach to this.
First off, you can load the json file from data and parse it using self.data.load:
let data = require('self').data;
let taps_data = JSON.parse(data.load('taps.json'));
This loads synchronously, so it isn't something you want to do often, in the example it would only happen when the add-on firsst becomes active in a browsing session.
Next, you would use content scripts and message passing to pass the data in to the panel.
In the main.js script:
panel.on('show', function() {
if (!loaded)
panel.port.emit('taps-data', taps_data);
});
In the content script:
self.port.on('taps-data', function(data) {
$('#list').html('');
data.forEach(function(item) {
$('#list').append('<div>'+ item.name +'</div>');
});
self.port.emit('taps-loaded');
});
I do a bit of extra work to make sure I'm only emitting the data once. The data, FYI, is saved from the live beer keg data api from my local pub.

Related

Hot to make visitors of my page automatically see the updated version (prevent caching) [duplicate]

Is there a way I can put some code on my page so when someone visits a site, it clears the browser cache, so they can view the changes?
Languages used: ASP.NET, VB.NET, and of course HTML, CSS, and jQuery.
If this is about .css and .js changes, then one way is "cache busting" by appending something like "_versionNo" to the file name for each release. For example:
script_1.0.css // This is the URL for release 1.0
script_1.1.css // This is the URL for release 1.1
script_1.2.css // etc.
or after the file name:
script.css?v=1.0 // This is the URL for release 1.0
script.css?v=1.1 // This is the URL for release 1.1
script.css?v=1.2 // etc.
You can check this link to see how it could work.
Look into the cache-control and the expires META Tag.
<META HTTP-EQUIV="CACHE-CONTROL" CONTENT="NO-CACHE">
<META HTTP-EQUIV="EXPIRES" CONTENT="Mon, 22 Jul 2002 11:12:01 GMT">
Another common practices is to append constantly-changing strings to the end of the requested files. For instance:
<script type="text/javascript" src="main.js?v=12392823"></script>
Update 2012
This is an old question but I think it needs a more up to date answer because now there is a way to have more control of website caching.
In Offline Web Applications (which is really any HTML5 website) applicationCache.swapCache() can be used to update the cached version of your website without the need for manually reloading the page.
This is a code example from the Beginner's Guide to Using the Application Cache on HTML5 Rocks explaining how to update users to the newest version of your site:
// Check if a new cache is available on page load.
window.addEventListener('load', function(e) {
window.applicationCache.addEventListener('updateready', function(e) {
if (window.applicationCache.status == window.applicationCache.UPDATEREADY) {
// Browser downloaded a new app cache.
// Swap it in and reload the page to get the new hotness.
window.applicationCache.swapCache();
if (confirm('A new version of this site is available. Load it?')) {
window.location.reload();
}
} else {
// Manifest didn't changed. Nothing new to server.
}
}, false);
}, false);
See also Using the application cache on Mozilla Developer Network for more info.
Update 2016
Things change quickly on the Web.
This question was asked in 2009 and in 2012 I posted an update about a new way to handle the problem described in the question. Another 4 years passed and now it seems that it is already deprecated. Thanks to cgaldiolo for pointing it out in the comments.
Currently, as of July 2016, the HTML Standard, Section 7.9, Offline Web applications includes a deprecation warning:
This feature is in the process of being removed from the Web platform.
(This is a long process that takes many years.) Using any of the
offline Web application features at this time is highly discouraged.
Use service workers instead.
So does Using the application cache on Mozilla Developer Network that I referenced in 2012:
Deprecated This feature has been removed from the Web standards.
Though some browsers may still support it, it is in the process of
being dropped. Do not use it in old or new projects. Pages or Web apps
using it may break at any time.
See also Bug 1204581 - Add a deprecation notice for AppCache if service worker fetch interception is enabled.
Not as such. One method is to send the appropriate headers when delivering content to force the browser to reload:
Making sure a web page is not cached, across all browsers.
If your search for "cache header" or something similar here on SO, you'll find ASP.NET specific examples.
Another, less clean but sometimes only way if you can't control the headers on server side, is adding a random GET parameter to the resource that is being called:
myimage.gif?random=1923849839
I had similiar problem and this is how I solved it:
In index.html file I've added manifest:
<html manifest="cache.manifest">
In <head> section included script updating the cache:
<script type="text/javascript" src="update_cache.js"></script>
In <body> section I've inserted onload function:
<body onload="checkForUpdate()">
In cache.manifest I've put all files I want to cache. It is important now that it works in my case (Apache) just by updating each time the "version" comment. It is also an option to name files with "?ver=001" or something at the end of name but it's not needed. Changing just # version 1.01 triggers cache update event.
CACHE MANIFEST
# version 1.01
style.css
imgs/logo.png
#all other files
It's important to include 1., 2. and 3. points only in index.html. Otherwise
GET http://foo.bar/resource.ext net::ERR_FAILED
occurs because every "child" file tries to cache the page while the page is already cached.
In update_cache.js file I've put this code:
function checkForUpdate()
{
if (window.applicationCache != undefined && window.applicationCache != null)
{
window.applicationCache.addEventListener('updateready', updateApplication);
}
}
function updateApplication(event)
{
if (window.applicationCache.status != 4) return;
window.applicationCache.removeEventListener('updateready', updateApplication);
window.applicationCache.swapCache();
window.location.reload();
}
Now you just change files and in manifest you have to update version comment. Now visiting index.html page will update the cache.
The parts of solution aren't mine but I've found them through internet and put together so that it works.
For static resources right caching would be to use query parameters with value of each deployment or file version. This will have effect of clearing cache after each deployment.
/Content/css/Site.css?version={FileVersionNumber}
Here is ASP.NET MVC example.
<link href="#Url.Content("~/Content/Css/Reset.css")?version=#this.GetType().Assembly.GetName().Version" rel="stylesheet" type="text/css" />
Don't forget to update assembly version.
I had a case where I would take photos of clients online and would need to update the div if a photo is changed. Browser was still showing the old photo. So I used the hack of calling a random GET variable, which would be unique every time. Here it is if it could help anybody
<img src="/photos/userid_73.jpg?random=<?php echo rand() ?>" ...
EDIT
As pointed out by others, following is much more efficient solution since it will reload images only when they are changed, identifying this change by the file size:
<img src="/photos/userid_73.jpg?modified=<? filemtime("/photos/userid_73.jpg")?>"
A lot of answers are missing the point - most developers are well aware that turning off the cache is inefficient. However, there are many common circumstances where efficiency is unimportant and default cache behavior is badly broken.
These include nested, iterative script testing (the big one!) and broken third party software workarounds. None of the solutions given here are adequate to address such common scenarios. Most web browsers are far too aggressive caching and provide no sensible means to avoid these problems.
Updating the URL to the following works for me:
/custom.js?id=1
By adding a unique number after ?id= and incrementing it for new changes, users do not have to press CTRL + F5 to refresh the cache. Alternatively, you can append hash or string version of the current time or Epoch after ?id=
Something like ?id=1520606295
<meta http-equiv="pragma" content="no-cache" />
Also see https://stackoverflow.com/questions/126772/how-to-force-a-web-browser-not-to-cache-images
Here is the MDSN page on setting caching in ASP.NET.
Response.Cache.SetExpires(DateTime.Now.AddSeconds(60))
Response.Cache.SetCacheability(HttpCacheability.Public)
Response.Cache.SetValidUntilExpires(False)
Response.Cache.VaryByParams("Category") = True
If Response.Cache.VaryByParams("Category") Then
'...
End If
Not sure if that might really help you but that's how caching should work on any browser. When the browser request a file, it should always send a request to the server unless there is a "offline" mode. The server will read some parameters like date modified or etags.
The server will return a 304 error response for NOT MODIFIED and the browser will have to use its cache. If the etag doesn't validate on server side or the modified date is below the current modified date, the server should return the new content with the new modified date or etags or both.
If there is no caching data sent to the browser, I guess the behavior is undetermined, the browser may or may not cache file that don't tell how they are cached. If you set caching parameters in the response it will cache your files correctly and the server then may choose to return a 304 error, or the new content.
This is how it should be done. Using random params or version number in urls is more like a hack than anything.
http://www.checkupdown.com/status/E304.html
http://en.wikipedia.org/wiki/HTTP_ETag
http://www.xpertdeveloper.com/2011/03/last-modified-header-vs-expire-header-vs-etag/
After reading I saw that there is also a expire date. If you have problem, it might be that you have a expire date set up. In other words, when the browser will cache your file, since it has a expiry date, it shouldn't have to request it again before that date. In other words, it will never ask the file to the server and will never receive a 304 not modified. It will simply use the cache until the expiry date is reached or cache is cleared.
So that is my guess, you have some sort of expiry date and you should use last-modified etags or a mix of it all and make sure that there is no expire date.
If people tends to refresh a lot and the file doesn't get changed a lot, then it might be wise to set a big expiry date.
My 2 cents!
I implemented this simple solution that works for me (not yet on production environment):
function verificarNovaVersio() {
var sVersio = localStorage['gcf_versio'+ location.pathname] || 'v00.0.0000';
$.ajax({
url: "./versio.txt"
, dataType: 'text'
, cache: false
, contentType: false
, processData: false
, type: 'post'
}).done(function(sVersioFitxer) {
console.log('Versió App: '+ sVersioFitxer +', Versió Caché: '+ sVersio);
if (sVersio < (sVersioFitxer || 'v00.0.0000')) {
localStorage['gcf_versio'+ location.pathname] = sVersioFitxer;
location.reload(true);
}
});
}
I've a little file located where the html are:
"versio.txt":
v00.5.0014
This function is called in all of my pages, so when loading it checks if the localStorage's version value is lower than the current version and does a
location.reload(true);
...to force reload from server instead from cache.
(obviously, instead of localStorage you can use cookies or other persistent client storage)
I opted for this solution for its simplicity, because only mantaining a single file "versio.txt" will force the full site to reload.
The queryString method is hard to implement and is also cached (if you change from v1.1 to a previous version will load from cache, then it means that the cache is not flushed, keeping all previous versions at cache).
I'm a little newbie and I'd apreciate your professional check & review to ensure my method is a good approach.
Hope it helps.
In addition to setting Cache-control: no-cache, you should also set the Expires header to -1 if you would like the local copy to be refreshed each time (some versions of IE seem to require this).
See HTTP Cache - check with the server, always sending If-Modified-Since
There is one trick that can be used.The trick is to append a parameter/string to the file name in the script tag and change it when you file changes.
<script src="myfile.js?version=1.0.0"></script>
The browser interprets the whole string as the file path even though what comes after the "?" are parameters. So wat happens now is that next time when you update your file just change the number in the script tag on your website (Example <script src="myfile.js?version=1.0.1"></script>) and each users browser will see the file has changed and grab a new copy.
Force browsers to clear cache or reload correct data? I have tried most of the solutions described in stackoverflow, some work, but after a little while, it does cache eventually and display the previous loaded script or file. Is there another way that would clear the cache (css, js, etc) and actually work on all browsers?
I found so far that specific resources can be reloaded individually if you change the date and time on your files on the server. "Clearing cache" is not as easy as it should be. Instead of clearing cache on my browsers, I realized that "touching" the server files cached will actually change the date and time of the source file cached on the server (Tested on Edge, Chrome and Firefox) and most browsers will automatically download the most current fresh copy of whats on your server (code, graphics any multimedia too). I suggest you just copy the most current scripts on the server and "do the touch thing" solution before your program runs, so it will change the date of all your problem files to a most current date and time, then it downloads a fresh copy to your browser:
<?php
touch('/www/sample/file1.css');
touch('/www/sample/file2.js');
?>
then ... the rest of your program...
It took me some time to resolve this issue (as many browsers act differently to different commands, but they all check time of files and compare to your downloaded copy in your browser, if different date and time, will do the refresh), If you can't go the supposed right way, there is always another usable and better solution to it. Best Regards and happy camping. By the way touch(); or alternatives work in many programming languages inclusive in javascript bash sh php and you can include or call them in html.
For webpack users:-
I added time with chunkhash in my webpack config. This solved my problem of invalidating cache on each deployment. Also we need to take care that index.html/ asset.manifest is not cached both in your CDN or browser. Config of chunk name in webpack config will look like this:-
fileName: [chunkhash]-${Date.now()}.js
or If you are using contenthash then
fileName: [contenthash]-${Date.now()}.js
This is the simple solution I used to solve in one of my applications using PHP.
All JS and CSS files are placed in a folder with version name. Example : "1.0.01"
root\1.0.01\JS
root\1.0.01\CSS
Created a Helper and Defined the version Number there
<?php
function system_version()
{
return '1.0.07';
}
And Linked JS and SCC Files like below
<script src="<?= base_url(); ?>/<?= system_version();?>/js/generators.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="<?= base_url(); ?>/<?= system_version(); ?>/css/view-checklist.css" />
Whenever I make changes to any JS or CSS file, I change the System Verson in Helper and rename the folder and deploy it.
I had the same problem, all i did was change the file names which are linked to my index.html file and then went into the index.html file and updated their names, not the best practice but if it works it works. The browser sees them as new files so they get redownloaded on to the users device.
example:
I want to update a css file, its named styles.css, change it to styless.css
Go into index.html and update , and change it to
in case interested I've found my solution to get browsers refreshing .css and .js in the context of .NET MVC (.net fw 4.8) and the use of bundles.
I wanted to make browsers refresh cached files only after a new assembly is deployed.
Buinding on Paulius Zaliaduonis response, my solution is as follows:
store your application base url in the web config app settings (the HttpContext is not yet available at runtime during the RegisterBundle...), then make this parameter changing according to the configuration (debug, staging, release...) by the xml transform
In BundleConfig RegisterBundles get the assembly version by the means of reflection, and...
...change the default tag format of both styles and scripts so that the bundling system generates link and script tags appending a query string parameter on them.
Here is the code
public static void RegisterBundles(BundleCollection bundles)
{
string baseUrl = system.Configuration.ConfigurationManager.AppSettings["by.app.base.url"].ToString();
string assemblyVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString();
Styles.DefaultTagFormat = $"<link href='{baseUrl}{{0}}?v={assemblyVersion}' rel='stylesheet'/>";
Scripts.DefaultTagFormat = $"<script src='{baseUrl}{{0}}?v={assemblyVersion}'></script>";
}
You'll get tags like
<script src="https://example.org/myscriptfilepath/script.js?v={myassemblyversion}"></script>
you just need to remember to to build a new version before deploying.
Ciao
2023 onward
At the time of writing, many web browsers support the Clear-Site-Data HTTP header [MDN reference]. To instruct the client web browser to clear the cache for the website domain and subdomains, set the following header in the HTTP response from the server:
Clear-Site-Data: "cache"
Alternatively, the following header may be better supported across browsers, but it clears other website data, such as localStorage and cookies, in addition to the cache.
Clear-Site-Data: "*"
However note that intermediate caches (e.g. a CDN) may not understand or respect this header, so intermediate caches may still respond with previously cached data.
Do you want to clear the cache, or just make sure your current (changed?) page is not cached?
If the latter, it should be as simple as
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">

How do I write a POST variable to a text file within SharePoint 2010

I’m working on a project that uses SharePoint 2010. I need to write a POST variable to a file using an ajax call.
If I were using PHP I would use the fwrite() function to write the POST to a file.
Here is how I envision my solution working. When you go to notarealwebsite.com and submit the form, I envision using an ajax call to write the file. The ajax on the index.php would look like:
$.ajax({
type: 'POST',
url: 'save-text.php',
data: {json: JSON.stringify(strJson)}
});
In PHP I would pass the POST variable into the save-text.php file and its code would look like this:
<? php
$file = fopen("file.txt","w");
fwrite($file, $_POST['json']);
fclose($file);
?>
Does SharePoint have an equivalent function I can use to save the POST to a file?
You don't give us too much here...
You can develop something in JavaScript using a third library like SharepointPlus with the createFile function
You'll do:
$SP().createFile({
content: JSON.stringify(strJson),
destination: "http://mysite/Shared Documents/file.txt",
url:"http://mysite/",
after:function() {
alert("File saved");
}
});
The createFile of SharepointPlus uses the CopyIntoItems web service of Sharepoint.
In SharePoint environment, you would most probably write these strings to list instead of file system. This is especially true if its some kind of configuration value because you want it accessible from all the frond end machines. A file on a filesystem will be created on just a single node where the code runs ultimately after the load balancer.
See:
How to: Create, Update, and Delete List Items
http://msdn.microsoft.com/en-us/library/office/ee539976(v=office.14).aspx

Localhost returns 404.3 when fetching json through ajax (Windows 8.1)

So I have been getting the infamous 404.3 error when trying to use AXAJ to access a .json file launching the site (or more of a test app hehe) through WebMatrix on localhost.
Yes, I am aware of the IIS configuration. I am on Windows 8.1(x64), so I had to even turn on MIME types functionality separately. I configured a MIME type for .json with application/javascript. Then I went and added a handler to *.json, pointed it to C:\WINDOWS\system32\inetsrv\asp.dll. I set the verbs to GET and POST (those are what I use in my ajax function). I also tried unchecking the "Invoke the handler only if request is mapped to..." to no avail.
I am using one function to send data to PHP file which writes it to the JSON file and then another to fetch data from the JSON file directly. Writing through PHP works. Fetching doesn't. I am completely at a loss, does anyone have any ideas? The code I am using to fetch the data is your bog-standard ajax:
function getDate(path, callback) {
var httpRequest = new XMLHttpRequest();
httpRequest.onreadystatechange = function() {
if (httpRequest.readyState === 4) {
if (httpRequest.status === 200) {
var data = JSON.parse(httpRequest.responseText);
if (callback) callback(data);
}
}
};
httpRequest.open('GET', path);
httpRequest.send();
}
When I host this on my server space, it works totally fine. But I want to get it to work locally for testing purposes as well.
If writing to the file works but fetching doesn't work. Then you should check for the link of the file.
The error 404 as the name refers to, is an error for the file name. There isn't any other sort of error, even the Ajax request is working fine and giving the error 404 (file not found). So the only thing that you can do is, to make sure that while fetching the data, you use the correct link.
Here can be a help, when you send the Request through Ajax, there is a Network tab in your Browser's console. Open it, and look for the request. It would in red color denoting an error and click it. You'll see that the link you're providing isn't valid.
Look for the errors in the File Link then and update it.
The lengths I go to, to clean up my profile...
When you require a JSON format, or any file for that matter you have to specify in your request what data type you need, IIS will not make any assumptions. So
xhr.setRequestProperty('Content-Type', 'application/json');
is something one must not forget. I set also the X-Requested-With header. Note that to reproduce this issue I used IIS that is installed on Windows 10 Pro, so not exactly the same system (3 years later - holy crap!).

Cross domain javascript ajax request - status 200 OK but no response

Here is my situation:
Im creating a widget that site admins can embed in their site and the data are stored in my server. So the script basically has to make an ajax request to a php file in my server to update the database. Right? Right :)
The ajax request works excellent when i run it in my local server but it does not work when the php file is on my ONLINE server.
This is the code im using:
var url = "http://www.mydomain.net/ajax_php.php";
var params = "com=ins&id=1&mail=mymail#site.net";
http.async = true;
http.open("POST", url, true);
http.onreadystatechange = function() {
if(http.readyState == 4 && http.status == 200) {
//do my things here
alert( http.responseText );
}
}
http.send(params);
In firebug it shows: http://www.mydomain.net/ajax_php.php 200 OK X 600ms.
When i check the ajax responnseText I always get a Status:0
Now my question is: "Can i do cross-domain ajax requests by default? Might this be a cross-domain ajax problem? Since it works when the requested file resides in my local server but DOESN'T work when the requested file is in another server, im thinking ajax requests to another remote server might be denied? Can you help me clear on this?
Thanks..
Cross-domain requests are not directly allowed. However, there is a commonly-used technique called JSONP that will allow you to avoid this restriction through the use of script tags. Basically, you create a callback function with a known name:
function receiveData(data) {
// ...
}
And then your server wraps JSON data in a function call, like this:
receiveData({"the": "data"});
And you "call" the cross-domain server by adding a script tag to your page. jQuery elegantly wraps all of this up in its ajax function.
Another technique that I've had to use at times is cross-document communication through iframes. You can have one window talk to another, even cross-domain, in a restricted manner through postMessage. Note that only recent browsers have this functionality, so that option is not viable in all cases without resorting to hackery.
You're going to need to have your response sent back to your client via a JSONP call.
What you'll need to do is to have your request for data wrapped in a script tag. Your server will respond with your data wrapped in a function call. By downloading the script as an external resource, your browser will execute the script (just like adding a reference to an external JS file like jQuery) and pass the data to a known JS method. Your JS method will then take the data and do whatever you need to do with it.
Lots of steps involved. Using a library like jQuery provides a lot of support for this.
Hope this helps.

Debugging Ajax code with Firebug

I've a couple of problems debugging code returned in an Ajax call - specifically, a function returned in json (errors don't get trapped in Firefox) - up to the point where I started debugging these problems in Internet Explorer (I think it's a firefox related problem, as Venkman doesn't detects those errors either) Do you know of any way to debug code returned in json from an Ajax call?
EDITED 03/04/2009 15:05
Thanks to all for your responses, but I think I didn't explain myself well enough. I know enough of Firebug to do basic debugging, but my problem happens when I fetch some code in an Ajax call that has a problem with it. Let's say we have the following HTML file (you'll need prototype in the same folder to make it work correctly):
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<script type="text/javascript" src="prototype.js"></script>
</head>
<body>
<script>
function ajaxErrorTest()
{
new Ajax.Request('data.json', {
'method': 'get',
'onSuccess': function(data){
if(data.responseJSON.func)
data.responseJSON.func();}});
}
</script>
<input type="button" value="test" onclick="ajaxErrorTest();" />
</body>
</html>
and then, the contents of the data.json file is this:
{'func':function(){console.log('loaded...');alert('hey');}}
If you load the page in a browser and click the 'Test' button (and everything goes well) you'll get something in the console, and an alert box that says 'hey'. Now change the data.json file to this:
{'func':function(){console.log('loaded...');alerts('hey');}}
...and click the 'Test' button again (no need to reload the page ;-)
You get the console line, but no alert box... and no errors!!! this is the kind of errors I'm trying to debug.
Try clicking on the "Console" panel (it's a tab) and enabling it. You will find that any HTTP requests will be caught along with any information that they contain. I use this in order to view any JSON stored in the request as well as any errors (500/404/etc).
Also be aware that you have to enable the console panel on a per-domain basis. There are usually three subtabs: headers, post, and response. I usually use the post/response tabs quite a bit when I'm debugging my AJAX.
You probably want to use the Net tab and filter the requests for XMLHttpRequests (XHR) only.
Additional tips:
don't hesitate to console.dir(yourObject) in your code or directly in the console panel. This will give you the complete state and properties of your object.
check your request/response HTTP headers; sometimes it's just a matter of encoding.
if you don't know what event/user action triggered this XHR call, you can add console.trace() right before your AJAX call. This way you'll get the complete call stack.
Edit:
Code executed in another context
The only way I came up with is surrounding your code with an (ugly) try/catch.
I guess it's because the code is executed in another javascript context
<script>
function ajaxErrorTest()
{
new Ajax.Request('data.json', {
'method': 'get',
'onSuccess': function(data){
try{
if(data.responseJSON.func)
data.responseJSON.func();}});
} catch (err) {
console.dir(err);
}
}
</script>
This code gives a detailed error message:
ReferenceError: alerts is not defined
I really doubt changing the execution context will solve the problem.
I don't know how to this with prototype, but with jquery, it can be done easily:
$.ajax({
url: "test.html",
context: document.body,
success: function(){
$(this).addClass("done");
}
});
I'm not sure this issue involves the actual JSON that is retrieved. Can you try throwing an error directly in your onSuccess handler and see if it appears in the Firebug console? Something like this:
onSuccess: function() { alerts('hey'); }
If this is the case, then this issue should be fixed in Firebug 1.7.
I would use a combination of the net/console tabs in firefox.
Copy the json results from the Net Tab in Firefox.
Then paste the results into a variable in the console and try executing the offending function.
In this case, I pasted this:
var x = {'func':function(){console.log('loaded...');alerts('hey');}}
x.func();
When I run this, firebug gives me this error.
ReferenceError: alerts is not defined
As others have mentioned, view the JSON/Javascript returned by expanding the AJAX URL in the Console tab.
Then if you copy that to the run/eval panel of the Console tab (there's an up/down arrow in the bottom right, clicking the up will change it into a textarea on the right hand side, clicking down gives a single line running along the bottom).
If your Ajax call returns: function(){alert("hello")}
Then you can use something like the following:
x = eval('function(){alert("hello")}')
x();
This will allow you to execute the returned ajax.
To debug with breakpoints use the HTML view to create a tag (using Firebug's HTML view) and then simply paste the code into a function within this tag. You can then set breakpoints and fire it by calling the previous function from the run'/eval panel.
If this works fine then clearly there's a bug outside of your control, but you could simply workaround that by sending the json back as text/plain, assigning it to a variable and then evaluating it.
This one is simple, i allways use FIDDLER
to debug my ajax calls.
Fiddler is a Web Debugging Proxy which
logs all HTTP(S) traffic between your
computer and the Internet. Fiddler
allows you to inspect all HTTP(S)
traffic, set breakpoints, and "fiddle"
with incoming or outgoing data.
Fiddler includes a powerful
event-based scripting subsystem, and
can be extended using any .NET
language.
I use an HTTP Proxy Debugger called fiddler which has always worked fine for debugging my AJAX problems. It captures all HTTP requests and responses for you to view. Its freely available from http://www.fiddlertool.com/
the error you are trying to debug is pretty visible on native firefox console. it is: "tools" - "error console"
of course, you see it after it ocurrs but with an wrong line number (infinite resemblance)
I know the specific issue mentioned in the post is for firefox. I landed on this page when googling for generally how to debug java script that comes from an AJAX call and I'm sure a lot of others will.
I my case I was returning some HTML that had a script tag in it, if there was for example, a sytax error in the javascript that came down from the AJAX request in firebug you will get no exception, or errors. The AJAX content will just not render.
In the google chrome built debugger you'll get the error that has been raised, but you'll not be able to step through the code. If you wan't to step though then you'll need to make a dummy page for that.
Thats the best I've been able to get it so far.
When you use a library or javascript code that you have loaded it dynamically, you can use the phrase //# sourceURL=foo.js at the beginning of your javascript code that foo.js is the name that assign it. debugger will show it with that name.
This is true in chrome that I think in firebug.
In this case you can place a breakpoint in the dynamically loaded javascript ( or json ) code.
Use "debbuger;" as line of code where you wanna stop execution. In this way the loaded source code will be available in the source section of your debbuger. I know for sure it works on chrome.

Resources