chrome extensions: Which will be better, ajax or chrome.extension.sendRequest? - javascript

Not just faster but better both in speed and using resources/memory.
I have an app where I put in suggestions as user types in an input-type-text. So, should I use ajax to communicate between two pages or chrome.extension.sendRequest?
EDIT
I have a packaged app, all the app info is stored in background.html's websql database. there is an input-type-text on index.html (which opens when someone clicks on app logo form new-tab page)
The input on the index.html fetches suggestions from the database of background.html as the user types in it. (just like google does when you start typing the query on google homepage) I can fetch suggestion data in two ways, using XmlHttpRequest and through chrome's message passing api. Since there will be a lot of requests to the background.html, i was wondering which method would be efficient..
The app in question: https://chrome.google.com/webstore/detail/fddboknafkepdchidokknkeidnaejnkh?hl=en-US
EDIT 2
The app is 100% offline. I am not connecting to any server or website. I am not loading any external script, not even jquery. All the app ever connects to is the files in it's own directory. background.html loads when pc starts and index.html loads when user clicks the app icon in new tab page. To see everything in action, you can install the app and see it for yourself.
EDIT 3
I am using the regular ajax to call index.html from background.html and it seems to work fine. By the way, both index.html and background.html are in 'html' directory.
function ajaxcall(url,callback) {
var call = new XMLHttpRequest();
call.onreadystatechange=function() {if(call.readyState==4) callback(call.responseText);}
call.open("GET",url+'#'+Math.random(),true);
call.send(null);
}
ajaxcall('/html/index.html', function(response) {console.log('foo')});

You should use the message passing API whenever you want to communicate between content scripts and your other pages. I don't see how you want to use ajax here.
If you're communicating between let's say your background page and the browseraction popup you could also use chrome.extension.getBackgroundPage which simply returns you the window object from the backgroundpage. Due to the restrictions imposed on content scripts you can't use this function in content scripts. This means you will always have to use message passing api for content scripts.
Don't be fooled by the asynchronous nature of these message passing functions. it's just a design consideration from the Chrome team to use asynchronous functions (with a callback) everywhere. It doesn't mean they take a lot of time to execute. Although I haven't bench-marked them, They seem to execute almost instantaneously.
Edit
I misinterpreted your question. I thought you were asking about how to communicate between the different pages in your extension/app. What you are really asking is how to communicate with a web server.
The message passing API (sendRequest) only works for communication between different parts of your app. The reason why this API is in place is because different parts of your app run in different environments, these are called isolated worlds. These environments are completely separated from each other to protect you from malicious code. The only pinhole through these different environments is this message passing API.
If you want to communicate with a web server ('pages' as you call them) you will need to use ajax. With ajax you will also notice the tight security model of Chrome. Under normal conditions a webpage is only permitted to make requests to the same site it originates from. This is called 'same origin policy'. because your extension/app is not hosted (it is packaged) it has no rights to access a web server by default. You, as a developer, will have to request this right to the user. You can do this by filling in the permissions property in the extension manifest. Whenever the user installs your app he has to accept that you have the right to access a certain web server.
As I read your question I am assuming you are still not very familiar with Chrome extensions, apps, Ajax and policy in a browser. I encourage you to read further on these topics while you are developing your app so you can ensure the security of your users.
Edit 2
Ok, so you're communicating between two different parts of your app, the index.html and the background.html. For this you can use getBackgroundPage and directly call functions defined in your background page. What you do is the following: In your backgroundpage:
window.getSuggestions = function(query) {
// search database for query
return ['suggestion1', 'suggestion2'];
};
Then you can call the following function on your main page (index.html):
var backgroundPage = chrome.extension.getBackgroundPage();
var mySuggestions = backgroundPage.getSuggestions('suggestion');
console.log(mySuggestions);
It's that simple. You don't need any ajax or sendRequest for this. No asynchronous code at all. You can just call a function in a synchronous fashion and this will be returned:
['suggestion1', 'suggestion2']
I didn't benchmark this and I haven't seen any data about it yet but I'm pretty sure this code is a lot faster than the message passing API or ajax. I didn't know you could use XmlHttpRequest within your extension but if it's possible I expect it to be the slowest way since you're actually making a network call in stead of calling to in-memory objects. If you want to be sure about the timings I suggest you to benchmark them yourself. You can easily do this with Chrome by using the following code:
console.time('someID');
// perform heavy operation(s) here.
console.timeEnd('someID');
The time to perform this operation will be printed to the console.
Edit 3
Now that I think about it, I'm not really sure how you would do ajax between two pages inside an extension. Don't you need a web server for this task? Can you give an example in your question of how you achieved this in your app?

Related

Simplest way to display API results

Im kind of new to this and looking to expand pulling API results and displaying them on page, whether it's from a blog resource or content generation.
For example, I want to pull from VirusTotal's API to display returned content. What is the best way to capture that in an input tag and display it in a DIV. And what if it were an option to pull from different API's based on drop down selection?
An example of the API to pull content would be here https://developers.virustotal.com/reference#api-responses under the /file/report section.
To call the data from the API, you need to send a request. However, there is a problem with CORS. Basically, you can't call the website from inside your web browser from a page on your local machine, because your browser blocks the request. The web browser will only allow calls to and from the same server, except for a few exceptions.
There's two ways to approach this.
The simplest one is to make a program that calls the API and outputs an HTML file. You can then open that HTML file to read the contents. If you want to update the info, you would need to run that program once again manually. You could easily do this building off the python they provided.
The other, little bit more complex way, is where you host a server on your PC. When you go to the webpage on that server, it sends a request to the website, and then provides the latest information. There's tons of frameworks and ways to do this. For an absolute beginner on this subject, ExpressJS is a good start. You can make a hello world program, and once you do that you can figure out how to call the API whenever a page is loaded, and display the results.

What is good way to render scorm 1.2 package in a web page?

We have some scorm 1.2 content hosted in our server and would like to integrate in our website. I didn’t find any good article that explains how to do it right way. I found lot of articles/tutorials explaining various apis and events about Scorm 1.2, Scorm 2004 and TinCan but none about integrating content in a html page.
Are there any good javascript libraries (scorm players?) that actually reads imsmanifest.xml file and render content?
There are a lot of questions like this on StackOverflow. And the web in general.
Server side Recipe:
Serverside script to allow the upload of a zip or FTP/SFTP, scp etc...
Serverside script to Unzip a Zip file (optional)
Serverside script to parse the imsmanifest.xml (one to many content objects)
SQL or NOSQL DB to store data (optional)
You need to control any launch data, and parameters as well as thresholds defined in the imsmanifest.xml required to launch the content.
Client Side Recipe:
You probably will want a UI for login/user management and assignments
Shareable Content objects commonly run within IFRAMEs, popup windows, new tabs or windows. Determine how you want to launch them.
You'll need a JavaScript SCORM Runtime exposed "API" for 1.2. You'll need to read up on the CMI Object and its namespaces/rules. Don't worry, most the specification is optional.
You'll need to use AJAX to submit the student attempt when they call commit. You'll want to control this with a 'sync' call in cases where the student has closed their browser, or was navigated away from your site. Else, you'll lose their data.
You could get away with localStorage vs the server side storage of data depending on your goals.
General flow for your site is to wait for the student to choose an assignment. Load their CMI Object (clean/new or suspended/resumed). Then load the SCO, wait for them to make calls against your JavaScript API.
Be very careful about not round tripping your back end on get and set value requests. Use the commit to do that so your not spamming your backend.

Javascript communication between two web applications on different domains

I have a web app, which is launched in a new pop-up window when a customer clicks a link on a Drupal web content page.
When the user reaches a certain page in the web application's workflow, I want to send a message to the (still open) Drupal page and pass it some information (like where in the workflow I'm up to).
When the Drupal website receives this 'message', it calls some javascript on its end to update the currently displayed page content.
So basically, a way to execute Javascript on one domain, from a Javascript function in another domain.
I have control over both the Drupal site and the web application so any javascript which needs to be deployed on either end isn't an issue. But note that the two sites are on different domains, so I need to implement something that will work cross-domain
I am not sure how to implement this, I have considered JSON-P so far.
Both your web apps are running at client-side, so you don't need to ask to server about how to contact with the window that you already opened.
So, to save time and effort, make a directly comunication between the windows at client-side.
To send a message to another html page, you need to first keep in a variable the window opened, as bellow:
// This code is inside the html file that open
// the drupal site.
var windowOpened = window.open("drupalUrl.html");
but, at drupalUrl.html you need to create a global function, so you can call like this:
windowOpened.globalFunction(param1, param2);
As I said, inside the drupalUrl.html you need to create a function:
function globalFunction(param1, param2){
//show your message
}

What's the best fallback if Google Ajax API is not available (since Google does not permit to install it locally)?

In my site I have:
...
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
...
The script above is the Google script to load up other resources dynamically.
(eg Google charts API)
This works 99.99% of the time.
However, I just got a client that for some reasons got his company restricting access to google.com.
As a consequence of this my website simply threw a JavaScript error.
Now I know how to handle that, and I can check if window.Google exists.
but my question is
"what's the standard way to deal with this? "
In other words if you embed 3rd party JavaScript how best do you deal with their JS not available?
NOTE: VERY IMPORTANT
You can not host the chart code locally or on an intranet.
SEE FAQ from Google: https://developers.google.com/chart/interactive/faq#localdownload
Can I download and host the chart code locally, or on an intranet?
Sorry; our terms of service do not allow you to download and save or
host the Google.load or Google.visualization code.
There is no real alternative. Due to Google's terms of service you cannot use Google API without access to google.com.
Check the connection to Google and iform user that function is not available
Develop your own or use non-google api. Still you can use Google if available
The solution is that your client's company review their content filtering policies. Google are quite clear in their previous answer concerning offline access:
…your computer must have live access to http://www.google.com/jsapi in order to use charts.
You are using a third-party solution according to their terms and conditions, which naturally imposes limits on how that solution may be used by your clients. You need to stand firm or find a more liberally-licensed solution. (At any rate, you are more likely to succeed at convincing your client's IT department than petitioning Google to change their TOS.)
For the more general case of third party JS APIs that may not load but for which you are allowed to keep a local copy on your server, see this question.
You can try it like this:
Instead of using the direct link to the Google libraries you want to use, use a link which points to your server:
<script type="text/javascript" src="https://www.myserver.com/jsapi"></script>
When your server gets an incoming request to this URL, your server now makes a request to Google to get the API and sends the response to the client.
That means you do not install the API anywhere locally or on a server and always get the most actual version directly from Google. People also do not need access to Google (as in the company you mentioned) and therefore can use your service.
Use Firebug or the Chrome Dev Tools to inspect your HTML source once the charts scripts are loaded. Access the scripts in your browser and save them locally, then serve them from your own server. This isn't recommended, of course, but if you don't have any other choice...
For example, checking the code of one of the pages I use it on, the core script for the Google Charts library is located at:
https://www.google.com/uds/api/visualization/1.0/3d781368978b51b3ca00a01566dccf40/format+en,default,corechart.I.js
Use the javascript window.onload to check whether the api has loaded or not, if no then load it from your server.
You already know how to check whether or not your library has been loaded (checking the object), if it fails, than what you can do within giving constrains:
Keep checking the object with timer and trying to download library, displaying message for a user
In case first one fails, you have two ways again:
Stopping your application and displaying an error: "Application error... try later"
Or downloading different library as a fallback
Are you progressively enhancing or gracefully degrading the page? If so, what do you display to users without JavaScript for this chart? A table? A list? This is what you should leave in the page and only start changing it once google's JS is available. Either that, or find an alternative library like raphaeljs that lets you keep all your code within your project.
IF (BIG IF) you are not worried about the interactivity the Google Charts and want to display them to the user just to see - maybe add your own javascript to it but not depend on the Google Javascript at all, this can turn the google charts into a image that you can display to the user.
Also this requires access to install a command line tool on the server.
http://code.google.com/p/wkhtmltopdf/ is a command line tool that will generate an image from an html page. If you build a simple page that only shows the chart you want and point the wkhtmltoimage tool at the local html file it will load the Google Charts javascript and generate the chart then generate an image out of the results.
YES I understand this is VERY kludgy and is adding a big tool for a small problem but with the browser restriction and the Google Terms of Service this will solve most of the problem.
You can try going straight to google and if it fails (if google is restricted) you can bounce the request off of your server which forwards the request using CURL to google. If that doesn't work then Google is most likely down. This should cover the issue that you described in your question, but there isn't really a fix for if google itself actually goes down. It should, however, give your application access around domain restrictions because the request will be routed to your server rather than straight to google. I use this architecture for all requests so that I don't have ajax requests routed to random servers. It allows me to control what interacts with my front end using my backend. There are other benefits to this, especially if you are using something like AngularJS with NodeJS because you can decouple a lot of your third party libraries. This however, is beyond the scope of your question!
Basically, it works like this (pseudo code):
If(!Browser->Google->Browser){
return Browser->MyServer->Google->MyServer->Browser;
}
An answer has been accepted already, but still I would like to leave an additional aspect elaborating on the comment I made above ....
It has been accepted that the Google Server is the only place from where the API can be loaded. We don't know whether the client's IT manager will re-think their content policy, they might have good reasons for that.
Given a non-100% availability of all the components along the path between a user browser and the Google API, sooner or later a user will end up in an error situation; statistically this is unavoidable.
What is not acceptable (and avoidable) for a user is to receive an "unspecific" JS error making him/her believe there's a bug on the page. So my solution would be to trap the failure loading the Google API and display a message "Third party components temporarily unavailable - Please try later".
This will demonstrate to the user that
we know what's going on
there's nothing we can do about it now
but it's not totally unexpected and still somehow under control

ColdFusion - Detect top window

is there a function in ColdFusion that detects whether or not a browser window is the top window? (Similar to (if (window == window.top)) in JavaScript)
The reason I ask is because I would like to make certain page elements present when the page is directly accessed by the user, and not present if my page is iframed.
CFML code runs on the CF server, whereas any considerations about browser windows obviously run on the client. CF is completely unaware of the UI configuration of the client system, all it sees is "a request". Indeed the requests don't even come from the client, they come from the web server which acts as a go-between for CF-serviced requests: CF has no interaction with the client itself.
The only information the web server gives to CF that in any way relates to the client browser is some of the stuff in the CGI scope, and obviously that's limited. And none of it relates to the configuration of browser windows / iframes.
You will need to solve this with Javascript (which I will add to the tags of your question).
To trigger different code to execute on CF given a certain browsing situation, you are going to need to use Javascript to add some information to the request to identify the situation to CF. This could be adding a parameter on the query string, or something like that.
If someone was 'wrapping' one of my products I'd want to know who and how so I could improve the experience for the user and the site owner. With that in mind, what I would do is automatically break out of any frames by default. I would then create a simple api and provide instructions to other webmasters on the proper way to include your content. Display different content once you've determined if your content is PROPERLY being included in another site. For webmasters that want to include your content:
Provide recommended height/width for the iFrame so you can
include your logo or ads with the content.
Provide anything you want them to include in the query string to help track usage.
You could even add fun stuff to your api to make your content look more integrated into the including website like reacting to url.bgcolor or url.bgimage.
You could go as simple as looking for and recording the value of some url variable like url.remoteSiteAddress or as complicated as registering the site and providing unique key. Of course there are other considerations to take into account to enforce the key. Being that you don't really care that the content is being displayed on a remote site, I suspect just recording a simple url variable is more your speed.
If a different website is putting your page in an iframe on their website, then you could use the CGI.HTTP_REFERRER variable to check if the website domain is yours or not, and load content as desired.

Categories