
Good day.
Today we will consider options for organizing cross-domain queries in userscripts.
I will not go into details of the implementation of this or that mechanism, but I will give an example of a
cross-browser shell for cross-domain queries .
Introduction
As you know, in its pure form in the natural environment of the browser environment, cross-domain queries are not trivial (thanks to
Same origin policy ).
Support for XMLHttpRequest with
CORS is not available in all browsers (in the opera it has not yet been encountered at all).
JSONP allows only GET requests, and proxying through frames forces you to use third-party libraries, or write creepy bikes.
Break: If you have read this far, and have not understood a word, then take a break, google unknown terms, drink tea. Do not be discouraged, further will be the explanation "on the fingers" and with the code. Beginner script writers can breathe easy: we will not go into details, but the working code and a drop of theory with all the links will be in your “zagashnik” .
')
The basics
What is the problem of cross-domain queries? All browsers limit our freedom for the sake of security. Therefore, requests from "untrusted" sources are suppressed in the bud. And what if we trust the sources? Correctly, use “crutches” (many of which are common practice).
As part of user scripts, you should take into account the restrictions imposed by the environment in which the scripts are run (details in
this article ), plus an additional important condition:
having access to the server part (having (or the ability to create) a server API to implement a specific query method)!
Below is a table that presents some of the “crutches” and their applicability for userscripts.
Method name + link | Short description | Requires access to the server | Can be used in user scripts |
---|
Jsonp
Article on Habré
| Only GET requests . Information is requested by inserting the <script> tag into the document body. The server response falls into the script body and is executed by the browser. At the same time, the script must define a “wrapper” function, which is transmitted from the server and is contained in the response.
| Access or JSONP API is required
| IE7 + Opera Firefox
|
XHR + CORS
Article on Habré Article on Mozilla Hacks
| The request is made via XMLHttpRequest (XHR) with specific request headers.
| Requires access or XHR CORS API
| IE8 + Firefox Chrome (extension)
|
iframe transport
| The request is made by placing an invisible i-frame in the document, which returns the response to the parent window. Pretty confusing way.
| Access required. The most convenient way is to use the easyXDM library (you need a little modification for Chrome and Firefox).
| IE7 + Firefox Opera Chrome (extension)
|
Native features of userscripts
| Specific to each browser. Not as a class in IE. Firefox + GreaseMonkey provide GM_xmlHttpRequest (similar to XMLHttpRequest), GET + POST requests. Chrome provides full cross-domain XMLHttpRequest, but only for extensions, GET + POST requests. Opera has a beforeScript event, with which you can make a GET request via <script> (not JSONP, therefore, access to the server is not needed).
| No server access required .
| Firefox Opera Chrome (extension)
|
For the vast majority of scripts,
access to the server is a critical parameter. In addition,
GET requests are most often
used (if the script is not malicious, not endowed with mega-intelligence or is not part of any service).
After reviewing the table soberly, you can make an approximate list of ways to organize cross-domain queries
for cross-browser user scripts :
- Chrome = packaging + proxying XMLHttpRequest (described in the third article )
- Firefox + GreaseMonkey = use GM_xmlHttpRequest
- Opera = use the beforeScript event and script transport
- IE7 + = use JSONP
Disadvantages:
- Only GET requests (not critical for 90%)
- For IE, you need access to the server or JSONP API (not critical for 90%, for the rest you can solve it through YQL )
- Nontrivial handling of transport errors
- For the opera will need an additional file
Learn more about GM_xmlHttpRequest
A full description of the object can be found
on the website Greasespot .
We also need to know that GM_xmlHttpRequest is an analogue of XMLHttpRequest and provides the same programming interface.
The function for sending a request may look like this (the setTimeout hack is applied to bypass the security error when accessing the user script code from an unsafe window when executing the request):
var GMTransport = function(url, onDone){ setTimeout(function(){GM_xmlhttpRequest({ method : "GET", url : url, onload : function(x) { var o = x.responseText; if (onDone) { onDone(o); } } });},0); }
BeforeEvent
This event is relevant only for Opera. Called when a script element appears in the document
before it is executed . The event can be intercepted and stopped the execution of the script. What we use.
Important: For Opera, you need to deliver a separate file in which the event will be hung. This is due to the peculiarities of the execution of custom scripts. Pay attention: there should be no metadata in the additional script ! The name of the script begins with an underscore, so that the script is loaded first.Link to additional script:
_opera-xdr-engine.jsThe code of the additional script
on pastebin.com .
The request is made by calling the following function:
var scriptTransport = function(url, onDone){ var t = document.createElement("script"); t.src = url; t._callback = onDone; document.body.appendChild(t); }
Note: For Opera, there is another solution: tyts . I didn’t pick it, but it’s probably better than the one presented here.Jsonp
JSONP implementation remains as homework :)
Fortunately, there are plenty of working examples on the net.
But first of all, you need to ask yourself: do you really need support for your user script in IE?
Understanding Chrome
To make queries in Chrome, you need to package the user script into an extension.
This method is described in detail in a
previous article . There is also an example of proxying a cross-domain query (the call to the query function can be found in the shell, below).
If you are
too lazy to follow the link, you read the article and know how to package the script, then the code for background.html
is available on pastebin .
Shell
All of the above methods are wrapped.
The code does not claim to be the “best code 2011” title, but is working and is used in various modifications in commercial userscripts (yes, there are some).
The shell code can be found on
pastebin.com .
Cross Domain Request Made By Call
xdr.xget(url, callback);
Determination of the desired transport occurs automatically.
- Learning to write userscript
- Userscripts. Go deep
- Userscripts. We pack user scripts for Chrome
- »Usersctripts. Cross Domain Queries