I can't seem to figure out a way to ignore the for(;;); in the response body of my cross domain JSONP requests. I am doing this on my own servers, nothing else going on here. I am trying to include that for(;;); inside the response body of my callback as such:
_callbacks_.callback(for(;;);[jsondata....]);
but how can I remove it from the response body before the JS code gets parsed? I am using the Google Closure Library btw.
Ok I think I figured it out.
The reason why the for(;;); is there is to prevent cross-domain data requests of certain information. So basically if you have information you are trying to protect you go through a normal Ajax JSON channel and if you are storing data on multiple servers you deal with it on server level.
JSONP requests are actually a remote script inclusion, which means whatever the server outputs is actual Javascript code, so if you have a for(;;); before your _callbacks_.callback(); the code will be executed on the origin domain on request success. If it's an infinite for loop, it will obviously jam the page.
So the normal implementation method is the following:
Send a normal Ajax request to a file located on the same server.
Perform the server level stuff and send requests to external servers via encrypted CURL.
Add security to the server response(a for(;;); or while(1); or throw(1); followed by a <prevent eval statements> string.
Get the response as a text string.
Remove your security implementations from the string.
Convert the string(which is now a "JSON string") to a JS Object/Array etc with a standard JSON parser.
Do whatever you want to do with the data.
Just thought I should put this out here in case someone else will Google it in the future, as I didn't find proper information by Google-ing. This should help prevent cross domain request forgery.
Related
Actually, I´ve create a Batch HTTP API that receives a JSON array with many different requests to our backend server. The Batch API just call all of these requests to a load balancer, wait for the return of all of them and return a new JSON to the client.
The client receives a huge JSON array response with its indices in the same position as the request, so it is easy to know what response is addressed for what request.
The motivation for this API was to solve the 5 browser simultaneous connections and improve performance as the Batch API has a much more direct access to the server (we do not have a reverse proxy or a SSL server between then).
The service is running pretty well, but now I have some new requirements as it is gaining more use. First, the service can use a lot of memory as it has a buffer for each request that will only be flushed when all responses are ready (I am using an ordered JSON Array). More, since it can take some time to all requests be delivered, the client will need to wait everything be processed before receiving a single byte.
I am planning change the service to return each response as soon it is available (and solve both issues above). And would like to share and validate my ideas with you:
I will change the response from a JSON response to a multipart response.
The server will include, for every part, the index of the response
The server will flush the response once its available
The client XHR will need to understand multipart content type response and be able to process each part as soon as it is available.
I will create a PoC to validate every step, but at this moment I would like to validate the idea and hear some thoughts about it. Here some doubts I have about the solution:
From what I read, I am in doubbt of that content-type is right for the response. multipart/mixed? multipart/digest?
Can I use an accept request header to identify if the client is able to handle the new service implementation? If so, what is the right accept header for this? My plan is to use the same endpoint but very accept header.
How can I develop a XHR client that is able to process many parts of a single response as soon as they are available? I found some ideias on the Web but I am not entirely confident with then.
I will change the response from a JSON response to a multipart
response.
The server will include, for every part, the index of the
response
The server will flush the response once its available
The
client XHR will need to understand multipart content type response and
be able to process each part as soon as it is available.
The XHR protocol will not support this work flow through a single request from the client. Since XHR relies heavily on the HTTP protocol for communications, XHR follows the HTTP connection rules. The first and most important rule: HTTP connections are always initiated by the client. Another rule: XHR returns the entire content-body or fails.
The implications for your workflow is that each part of the multipart response must be requested individually by the client.
From what I read, I am in doubbt of that content-type is right for the
response. multipart/mixed? multipart/digest?
You should be in doubt as there is no provision in the specfication to do this. The response-type attribute is limited to the empty string (default), "arraybuffer", "blob", "document", "json", and "text". it is possible to set the override MIME type header, but that does not change the response type. Event given that case, the XHR spec is very clear about what it will send back. It is one of the types listed above as documented here.
Can I use an accept
request header to identify if the client is able to handle the new
service implementation? If so, what is the right accept header for
this? My plan is to use the same endpoint but very accept header.
Custom HTTP headers are designed to assist us in telling the server what our capabilities are on the client. This is easily done. it doesn't necessarily have to be in the accept header (as that also is a defined list of MIME types).
How
can I develop a XHR client that is able to process many parts of a
single response as soon as they are available? I found some ideias on
the Web but I am not entirely confident with then.
XHR is processed natively by the client and cannot be overridden for all sorts of security reasons. So this is unlikely to be available as a solution for this reason.
Note: ordinarily one might suggest the use of a custom version of Chromium, but your constraints do not allow for that.
I have to send (and receive) certain data to a server using JQuery and JSON.
Works so far, but not cross domain, and it has to be cross domain.
I looked how to solve this and found JSONP. As far as I see, using JSONP I have to send the callback and the data using GET (JQuery allows to use "POST" as method, but when I inspect web traffic I see it is sending actually GET and everyting as parameter).
JSONP also requires changes in the server, because they are expecting a POST request with JSON data, and they have to implement something to process the JSONP GET request.
So I'm wondering what's the difference between this and sending the data as key value parameters in GET request?
Is the difference the possibility to use a callback? Or what exactly?
Sorry a bit lost... thanks in advance
JSONP is not a form submission. It is a way of telling the server via a GET request how to generate the content for a script tag. The data returned is a payload of JavaScript (not just JSON!) with a function call to a callback which you (by convention) reference in the GET request.
JSONP works because it is a hack that doesn't use AJAX. It isn't AJAX and you should not confuse it for such because it does not use a XMLHttpRequest at any point to send the data. That is how it gets around the Same Origin Policy.
Depending on the browsers you have to support, you can implement Cross-Origin Resource Sharing headers on the server side which will let you use normal AJAX calls across trusted domains. Most browsers (IE8, Firefox 3.5+, etc.) will support CORS.
Another solution you can use if you don't want to use CORS or JSONP is to write a PHP script or Java servlet that will act as a proxy. That's as simple as opening a new connection from the script, copying all of the incoming parameters from your AJAX code onto the request and then dumping the response back at the end of your script.
I found an answer that worked for me with the cross-domain issue and JSON (not JSONP).
I simply used:
header('Access-Control-Allow-Origin: *');
inside my json file (file.php) and called it like this:
var serviceURL = 'http://your-domain.com/your/json/location.php'
$.getJSON(serviceURL,function (data) {
var entries = data;
//do your stuff here using your entries in json
});
BTW: this is a receiving process, not sending.
I'm jusing jQuery's $.getJSON() function to return a short set of JSON data.
I've got the JSON data sitting on a url such as example.com.
I didn't realize it, but as I was accessing that same url, the JSON data couldn't be loaded. I followed through the console and found that XMLHttpRequest couldn't load due to Access-Control-Allow-Origin.
Now, I've read through, a lot of sites that just said to use $.getJSON() and that would be the work around, but obviously it didn't work. Is there something I should change in the headers or in the function?
Help is greatly appreciated.
It's simple, use $.getJSON() function and in your URL just include
callback=?
as a parameter. That will convert the call to JSONP which is necessary to make cross-domain calls. More info: http://api.jquery.com/jQuery.getJSON/
You may well want to use JSON-P instead (see below). First a quick explanation.
The header you've mentioned is from the Cross Origin Resource Sharing standard. Beware that it is not supported by some browsers people actually use, and on other browsers (Microsoft's, sigh) it requires using a special object (XDomainRequest) rather than the standard XMLHttpRequest that jQuery uses. It also requires that you change server-side resources to explicitly allow the other origin (www.xxxx.com).
To get the JSON data you're requesting, you basically have three options:
If possible, you can be maximally-compatible by correcting the location of the files you're loading so they have the same origin as the document you're loading them into. (I assume you must be loading them via Ajax, hence the Same Origin Policy issue showing up.)
Use JSON-P, which isn't subject to the SOP. jQuery has built-in support for it in its ajax call (just set dataType to "jsonp" and jQuery will do all the client-side work). This requires server side changes, but not very big ones; basically whatever you have that's generating the JSON response just looks for a query string parameter called "callback" and wraps the JSON in JavaScript code that would call that function. E.g., if your current JSON response is:
{"weather": "Dreary start but soon brightening into a fine summer day."}
Your script would look for the "callback" query string parameter (let's say that the parameter's value is "jsop123") and wraps that JSON in the syntax for a JavaScript function call:
jsonp123({"weather": "Dreary start but soon brightening into a fine summer day."});
That's it. JSON-P is very broadly compatible (because it works via JavaScript script tags). JSON-P is only for GET, though, not POST (again because it works via script tags).
Use CORS (the mechanism related to the header you quoted). Details in the specification linked above, but basically:
A. The browser will send your server a "preflight" message using the OPTIONS HTTP verb (method). It will contain the various headers it would send with the GET or POST as well as the headers "Origin", "Access-Control-Request-Method" (e.g., GET or POST), and "Access-Control-Request-Headers" (the headers it wants to send).
B. Your PHP decides, based on that information, whether the request is okay and if so responds with the "Access-Control-Allow-Origin", "Access-Control-Allow-Methods", and "Access-Control-Allow-Headers" headers with the values it will allow. You don't send any body (page) with that response.
C. The browser will look at your response and see whether it's allowed to send you the actual GET or POST. If so, it will send that request, again with the "Origin" and various "Access-Control-Request-xyz" headers.
D. Your PHP examines those headers again to make sure they're still okay, and if so responds to the request.
In pseudo-code (I haven't done much PHP, so I'm not trying to do PHP syntax here):
// Find out what the request is asking for
corsOrigin = get_request_header("Origin")
corsMethod = get_request_header("Access-Control-Request-Method")
corsHeaders = get_request_header("Access-Control-Request-Headers")
if corsOrigin is null or "null" {
// Requests from a `file://` path seem to come through without an
// origin or with "null" (literally) as the origin.
// In my case, for testing, I wanted to allow those and so I output
// "*", but you may want to go another way.
corsOrigin = "*"
}
// Decide whether to accept that request with those headers
// If so:
// Respond with headers saying what's allowed (here we're just echoing what they
// asked for, except we may be using "*" [all] instead of the actual origin for
// the "Access-Control-Allow-Origin" one)
set_response_header("Access-Control-Allow-Origin", corsOrigin)
set_response_header("Access-Control-Allow-Methods", corsMethod)
set_response_header("Access-Control-Allow-Headers", corsHeaders)
if the HTTP request method is "OPTIONS" {
// Done, no body in response to OPTIONS
stop
}
// Process the GET or POST here; output the body of the response
Again stressing that this is pseudo-code.
I need to send data to a remote server using javascript. How do I do this?
Background info:
There's a webpage from which I extract some information using JS, and I need to send it back to another server for processing. Response is not neccesary. The data is XML, Which I've URLencode'd.
How would one do this?
EDIT
The server I'm requesting the data from is not the same that receives the data. Just to clarify.
One of the most common ways to do this is AJAX. Here's how you perform an AJAX post request using jQuery:
<script type="text/javascript">
$.post('/remote-url', {xml: yourXMLString });
</script>
On the server side you process it like any other POST request. If you're using PHP it's $xml = $_POST['xml'];
The biggest limitation of AJAX is that you're only allowed to make requests to the same domain the document has been loaded from (aka cross-domain policy). There are various ways to overcome this limitation, one of the easiest one is JSONP.
UPD. For cross-domain requests an extremely simple (though not universal) solution would be:
(new Image).src = 'http://example.com/save-xml?xml=' + escape(yourXMLString)
This will issue a GET request (which cannot exceed 2KB in Internet Explorer). If you absolutely need a POST request or support for larger request bodies you can either use an intermediate server-side script on your domain or you can post a dynamically created html form to iframe.
submit a form using POST. That is working on all browsers cross domains. Have the server process the post. the form can be submitted to a hidden frame if you want to simulate AJAX
Use Cross Domain Resource Sharing (MDC) (IE XDR)
use a web bug (create an image, set the source to the url you want - smallish GET requests only)
var img = new Image();
img.src="http://www.otherserver.com/getxml?xml="+encodeURIComponent(yourXML);
(Oops, I see Lebedev did more or less the same in his update)
use a proxy, i.e. have your server talk to the other server for you
Look into Javascript's XMLHTTPRequest method -- or start with a Google search for AJAX. There's lots of ways to do this -- including some very easy ways through JS libraries like jQuery -- but a more specific answer would require some more specifics on the specific technologies you're using.
EDIT: You can set up the AJAX request to post to a server-side script (acting as a proxy) on your own domain, and have that script turn around and post the data to your remote server.
Should be done with the site number 1 request to the site number 2. Let the number one site will be localhost, and the site number 2 - the real server on the Internet. At site 2 there is a file result.php, which takes GET-requests:
$var = #$_GET['q'] ;
$s = $_GET['s'] ;
$typefile = $_GET['type'];
If the page result.php make a request, then we obtain the URL: result.php?q=%F4%FB%E2&type=1&search=%CF%EE%E8%F1%EA%21
How better to make a request? Can someone show me some examples to help? For 4 days I suffer, does not realize.
If somewhere is not clear written excuse my bad English with.
I'm assuming you mean with Ajax? You can't make cross-site domain requests through normal ajax due to the same origin policy. As such, a script hosted on localhost, can only make requests to localhost.
Now, you can get around this with JSONP, or JSON with padding. This allows you to append a script file to the dom from any source so the code can execute on your site. Personally, I've actually never used it and I understand you have to trust the origin of the script, you don't want arbitrary code being run on your site.
So in a nutshell, if you want localhost to make a request to 'site-2' you need to host a script on 'site-2' that gets loaded by your localhost and makes the request.
After reading what brad just said, what i would do is to add another chain to the request.
I'll be calling a local serverside script (cross domain proxy) that will request and process the data from the other server.
References
Cross-Domain Proxy
Same Origin Policy