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.
Related
I've seen many examples for JSONP but I can't seem to get any to work for my website. It can generate a JSON code at some url but I can't retrieve it from a different domain. Can you please give me a working example of JSONP that can retrieve data from any JSON file (eg. www.w3schools.com/json/myTutorials.txt).
I may not fully understand, but I just need an explanation, at least, of why if I replace a url with the example above, no data is being pulled.
This is a modified version of the example in the jquery docs using Yahoos public APIs.
$.ajax({
url: "https://query.yahooapis.com/v1/public/yql",
// Tell jQuery we're expecting JSONP
dataType: "jsonp",
// Tell YQL what we want and that we want JSON
data: {
q: "show tables",
format: "json"
},
// Work with the response
success: function( response ) {
console.log( response ); // server response
}
});
Along with a jsbin: https://jsbin.com/tuketa/edit?js,output
The reason for the existence of JSONP is to get around the limitations of CORS rules. For security reasons your browser, in general, is only allowed to communicate to the server it loaded the page from. JSONP was created to get around this by giving the server a callback function with which to pad the JSON data, hence the P in JSONP.
As noted in the comments by jasonscript, it's not any server that can function with JSONP, it has to be configured be able to work with JSONP such as the Yahoo API in the example.
There's many answers out there pointing out the difference between JSON and JSONP. Your question ("...jsonP that can retrieve...") shows that you didn't fully understand the concept. JSONP is a format of answer, as is HTML, XML, JSON. And so the server that responds the request should be able to send it JSONP formatted.
from a different domain... from any json file... it's not possible. The server response it's actually a javascript that wraps a json object.
jsonP is a protocol. the requester (the javascript in the browser) can't request via XHR (ajax) outside the source server:port due the Same-Origin-Policy (SOP).
To bypass the SOP, JSONP born.
The client does not send a XHR request, instead adds a <script> tag to the DOM, with the src attribute pointing to the URL of the jsonP with a parameter (e.g. callback=foo) which tells the name of the local function who receives the JSON as parameter.
Then, the remote server -who understands JSONP- sends a javascript who calls the local function with the JSON as parameter.
Like this example:
Client javascript code:
function foo(data)
{
// do stuff with JSON
}
var script = document.createElement('script');
script.src = '//example.com/path/to/jsonp?callback=foo'
document.getElementsByTagName('head')[0].appendChild(script);
(taken from here)
Server Response:
HTTP/1.1 200 OK
Content-Type: text/javascript
foo({ "key" : "value" });
So, the browser loads the script, calls foo with the json as parameter. Now, You have bypassed the SOP restrictions.
I am trying to Get Data from another url using JavaScript but failed , I tried All Solution from jsfiddle and Stack-overflow but one error is not going away
http://renault.twobulls.com/?code=waeuhh (Destination URL)
I tried $.getJson,$.ajax, and all even jsonp too...please help me out, I have this error when I use call back in url for jsonp
Error:
Does anyone have a solution?
You are making a JSONP request but the server is responding with JSON.
A JSONP response needs to be a JavaScript program that calls the function you specify as the callback in the URL with a single argument (which is the JSON payload).
Either change the server to make it respond with JSONP or change the JavaScript so it makes an XHR request (note that you will need to ensure the server allows a cross-origin XHR request using CORS).
Just assign it to a variable.
var someVar = {"code":"waeuhh","photoid":"1417564891877515"};
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.
Ho can i bypass this restriction?
I know i can use some kind of a proxy but not sure how this proxy should look like?
Any other suggestions?
Here is a pretty straightforward tutorial: http://developer.yahoo.com/javascript/howto-proxy.html
Basically, you make a service that takes an xmlhttprequest and have to request data from the external domain, and then return the result.
JSONP is exactly for that purpose
JSONP or "JSON with padding" is a
complement to the base JSON data
format, a pattern of usage that allows
a page to request data from a server
in a different domain. As a solution
to this problem, JSONP is an
alternative to a more recent method
called Cross-Origin Resource Sharing.
Here is the very very basic example of JSONP implementation.
The server side code -
public string GetFirstName()
{
string callback = Request.QueryString["callback"];
string resultJson = "{\"FirstName\": \"archil\"}"; //should definitely be some more application specific data :)
if (!string.IsNullOrEmpty(callback))
{
return string.Format("{0}({1})", callback, resultJson);
}
return resultJson;
}
This method is mapped to /GetFirstname URL on server. It is extacting callback argument from query string. And wrapping generated resultJson as javascript function call where name of function is parameter passed with callback.
on the client side, using jQuery - implementation is as simple as
$(function () {
$.ajax('http://serverUrl/GetFirstName', {
dataType: 'JSONP',
jsonpCallback: 'alert'
});
});
This will pass function name alert as callback for server. Server will return alert({"FirstName": "archil"}). jQuery will automatically inspect this response and execute it. As the result, you will get standart alert screen in browser. Main idea is that alert is executed will the server's return parameters. You could pass more specific function name as jsonpCallback and act on results of request.
I KNOW that the URL pattern used here is more like RPC style web service than REST style, but the example is about using JSONP, not about REST architecture
You can use $.ajax() call.
This has property crossdomain: which handles the cross domain request.
http://api.jquery.com/jQuery.ajax/
For cross domain request using jquery have a look at the
http://net.tutsplus.com/tutorials/javascript-ajax/quick-tip-cross-domain-ajax-request-with-yql-and-jquery/
Here are basic steps to create such proxy.
Create server side page (using server side language like PHP or ASP.NET it doesn't really matter) and call it for example "MyProxy.aspx"
In the server side code read the data sent either on URL or as POST data, and send that data as Web Request (in case of .NET, there's surely equivalent in PHP and other languages) to the external website.
Parse the result sent from the external website and send it back to the client.
In the client, send AJAX request to the proxy page (e.g. MyProxy.aspx) passing it the proper data, and handle the response.
Let us know what server side language you're using for more technical help to implement the above.
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.