Using JSONP to get XML - javascript

For two days, I have got around lots of forum sites, but I don't find exact solution of my problem.
I have cross-site scripting problem. Web services of my application that is written with javascript, html and css get an error like;
"XMLHttpRequest cannot load...bla bla bla..Origin http://localhost:8088 is not allowed by Access-Control-Allow-Origin response header." Code I write is;
$.ajax({
async: false,
type: "GET",
url: "http://www.yem...om/Cata.../M...ogin2?username=blabla&password=blabla123",
dataType: "xml",
success: function(xml) {
alert("CONTROL???");
$(xml).find('Login').each(function(){
var logResult = $(this).find('Result').text();
alert(logResult);
});
}
})
;
I see that I have to use JSONP. But when I write dataType: "*jsonp xml*" or dataType: "*jsonp text xml*", I get an error msg such as "SyntaxError: Parse Error" !
Also, I tried CORS Filter, but it needs web.xml but I don't have it. When I created and tried to work it, I failed!
Moreover, I tried cross domain requests with jQuery by James Padolsey http://james.padolsey.com/javascript/cross-domain-requests-with-jquery/
It works, but I haven't parsed data I receive. This plug-in uses Yahoo Query Language, because of that, controlling the data is different and not easy.
Is there any way left to figure my problem out? Please help me!
Best wishes.

The cross domain restrictions exist for a reason. It protects internet users. It is in place to prevent programmers and hackers from doing a lot of harmful things.
There are some things that you can do to get around it. One of them being that you can do CORS Filter to allow requests from cross domains. You say that you don't have web.xml file. I am not sure what your project looks like, but if you are using web services, then should have some sort of a web.xml file somewhere. If you can't set that up, you are out of luck (short of using a nice proxy like YQL or something similar). Things like YQL, they have set their CORS Filter to allow requests from all domains. Calling YQL is an ajax call, just like the ajax call that you are trying to do. The big difference is that the YQL server has the CORS Filter setup, which the browser detects and allows the cross-domain request to proceed.
Once a CORS Filter is in place, then the browser will allow you to hit that domain from a different domain. Rather than looking for a way to hack that, you need to get your project set up to allow the cross origin requests.
If you don't control the webservices that you are trying to ping, then you are out of luck. Only the owner of the webservices will have access to the web.xml.

To get results in JSONP, append this to the end of the URL: &callback=?
Try this:
$.getJSON('http://www.yem...om/Cata.../M...ogin2?username=blabla&password=blabla123&callback=?', function(xml) {
alert("CONTROL???");
$(xml).find('Login').each(function(){
var logResult = $(this).find('Result').text();
alert(logResult);
});
});
Cross domain scripting must be enabled on server side, too.

I was stuck with a similar problem as well. I found the solution to this question fixed my XSS problem:
'No Transport' Error w/ jQuery ajax call in IE
You do not have to use JSONP, as CORS works with an XML response. Did you try setting the support.cors property to true (solution in the above question)?
$.support.cors = true;

You can write XML in Javascript function inside in /* comment */ and convert this function to text with method functionname.toString() and parsing text between "/*" and "*/" with JSONP's callback function, that works in all old browsers. Example xml_via_jsonp.js :
function myfunc()
{/*
<xml>
<div class="container">
<div class="panel panel-info col-lg-10 col-lg-offset-1 added-panel">
<div class="panel-heading">Random1 - Random2</div>
<div class="panel-body">
<div>Random3</div>
</div>
</div>
</div>
</xml>
*/}
function callback(func)
{
var myhtml = func.toString();
var htmlstart = myhtml.indexOf('/*');
var htmlend = myhtml.lastIndexOf('*/');
return myhtml.substr(htmlstart+2, htmlend-htmlstart-2);
}

Related

Ajax Callback function's location

I had a problem about callback function which was located in $(document).ready . Callback function didn't used to work. When I put it outside of $(document).ready the code has started to work perfectly. I don't understand why. Is location is important?
This works:
$(document).ready(function() {
$("#button1").click(function() {
$.ajax({
url: "http://www.example.com/data.php",
type: "get",
dataType: "jsonp",
jsonpCallback: "read",
});
});
});
var read = function(data) {
console.log(data);
}
This does not work.
$(document).ready(function() {
$("#button1").click(function() {
$.ajax({
url: "http://www.example.com/data.php",
type: "get",
dataType: "jsonp",
jsonpCallback: "read",
});
});
var read = function(data) {
console.log(data);
}
});
UPDATE1: Sorry guys, links werent't different. I forgot to change 2nd one. There is just one difference that location of read function.
The reason you pass in the JsonP callback name as a string like that is because JQuery needs to add it to your URL like this ?callback=read. A JsonP request is just a <script> tag created by JQuery in the background and added to the page <script src="http://www.csstr.com/data.json?callback=read"></script>. Once JQuery adds that script tag to your page the browser will treat it like it's loading a normal JavaScript document to be exectued. Because of the ?callback=read part of the request, the remote server knows to respond with executable JavaScript and not just the raw data. That executable JavaScript is just a function call to a function with the name you provided, in this case the read function. Because the returned script is being executed in the global scope, the read function also needs to exist in the global scope. The global scope in the browser is the window object, so basically the read function needs to be present on the window object in order for the executed script to find the function.
$(document).ready(function() {
$("#ara-button").click(function() {
$.ajax({
url: "http://www.csstr.com/data.json",
type: "get",
dataType: "jsonp",
jsonpCallback: "read",
});
});
window.read = function(data) {
console.log(data);
}
});
It works outside of the ready function in your first example because anything defined at the root level like that is globally scoped.
Codpen Demo: http://codepen.io/anon/pen/qNbRQw
If you want to know more about how JsonP works, read on.
If you're still confused it's probably because you're not 100% familiar with how JsonP actually works. JsonP is a hack to get around the Same-origin Policy. The short version of the Same-origin Policy is that the browser won't let you read the response returned from requests to domains other than the one the request originated from unless the server on that other domain says it's okay.
The Same-origin Policy was implemented by most browsers to help protect users from malicious scripts. For example, if you authenticated with your bank website in one browser tab and then went to a nefarious website in another tab, without same-origin restrictions in the browser that nefarious site could make an ajax request to your bank website. That request would carry any cookies your browser has stored for that domain and your cookies would show you as authenticated, thus giving the attacking script access to authenticated data from your bank account. The Same-origin Policy prevents the nefarious site from being able to see the response data from that request.
In the beginning there was no official way for the client and server to opt-in to cross-domain sharing. It was just straight up blocked by the browsers at the time. To get around this JsonP was invented. The Same-origin Policy only hides the response from ajax requests, but as you may have noticed the browser is totally fine with loading scripts from other websites via <script> tags. The script tag just does a plain old GET request for a javascript document, then starts executing that script on your page. JsonP takes advantage of the fact that same-origin restrictions don't apply to <script> tags.
Notice if you go directly to http://www.csstr.com/data.json in your browser you'll see the data you're after. However, try going there with the following query string added.
http://www.csstr.com/data.json?callback=read
Notice anything different? Instead of just returning the data you want the response comes back with your data being passed into a function named read. This is how you know the server understands the JsonP hack. It knows to wrap the data you want in a function call so that JQuery can perform the JsonP hack on the client, which it does by creating a <script> tag and embedding it in your web page. That script tag points to the URL but also adds that querystring to the end of it. The result is a script tag that loads a script from that URL and executes it. That script is being loaded into your page's global scope, so when the read function is called it expects that function to also exist in the global scope.
Today, the official way around the Same-origin Policy is via the Cross-origin Resource Sharing policy (aka CORS). JsonP essentially accomplishes the same thing that a proper CORS request does. The server has to opt-in by knowing how to format the response as executable JavaScript, and the client has to know not to do a normal ajax request but instead dynamically create a script tag and embed it in the page body. However, JsonP is still a hack and as hacks do it comes with its own set of downsides. JsonP is really hard to debug because handling errors is almost impossible. There's no easy way to catch errors if the request fails because the request is being made via a <script> tag. The <script> tag also lacks control over the format of the request being made; it can only make plain GET requests. The biggest downside to JsonP is the need to create a global function to be used as a callback for the data. Nobody likes polluting the global namespace but for JsonP to work it's required.
Proper CORS requests don't require extra effort on the client's part. The browser knows how to ask the server if it is allowed to read the data. The server just has to respond with the right CORS headers saying its okay and then the browser will lift the same-origin restrictions and allow you to use ajax as normal with that domain. But sometimes the resource you're trying to hit only knows JsonP and does not return proper CORS headers so you have to fallback on it.
For more info about CORS I wrote a pretty detailed blog post a little while ago that should really help you understand it. If you control the server that is returning the data you're after then you should consider just having it return the proper CORS headers and forget about JsonP. But it's totally understandable when you don't control the server and can't configure it to return the proper headers. Sometimes JsonP is the only way to get what you need, even if it does make you throw up in your mouth a little bit as you write the code.
Hope that helps clear some things up for you :)
$(document).ready(function() { means : Do it when the page finished to load.
In the second example, you are defining the read function only after the page finished to load.
In the working example, you are defining the read function first and say, "Once the page will be loaded, do the ajax call and then, call read function"
Edit : Also, you can read #IGeoorge answer for a more detailed explaination.
Add read method before ajax
$(document).ready(function() {
var read = function(data) {
console.log(data);
}
$("#ara-button").click(function() {
$.ajax({
url: "http://www.csstr.com/data.json",
type: "get",
dataType: "jsonp",
jsonpCallback: "read",
});
});
});
Your function is defined into Jquery Scope, so at the moment the ajax is executed, cannot find definition of "read" function.
That's why the first example works.
Hope this helps.

How to implement jquery crossDomain

Trying to get my html/JS file to read and print firstName from this link:
http://www.w3schools.com/jquery/demo_ajax_json.js, as trial for something else I want to do.
Received this error: Origin null is not allowed by Access-Control-Allow-Origin, so trying to use crossDomain.
Read this: jquery API but not sure how to implement correctly
My JS code (I know it's off, but no idea how to correct it):
var myArray = [];
var jsonArrayObj;
$.ajax{
crossDomain: true}).done(function(){
$(document).ready(function(){
myArray = $.getJSON("http://www.w3schools.com/jquery/demo_ajax_json.js", function(result){
myArray = JSON.parse(myArray);
console.log(myArray.firstName);
});
});
});
I don't understand what function() does in JS either
You cannot use CORS to access a website unless the website allows you to do so. If CORS was allowed on that endpoint, there would be an HTTP header for Access-Control-Allow-Origin: * (or a specific hostname). So the server you are attempting to talk to has to have a header allowing this to happen.
That endpoint works on the w3schools getJSON() demo page because the JavaScript is running from the same domain as the XHR target (so CORS is not needed).
More here: MDN: HTTP access control (CORS)
JSONP/JSON-P is an alternative to CORS but that endpoint doesn't appear to support it either (at least not with the typical callback querystring key).
Its because of CORS. Try to load file locally.
In your code you are using anonymous function. Internet is full of pages to read about javascript functions.
FUNCTIONS:
http://www.w3schools.com/js/js_functions.asp
https://en.wikibooks.org/wiki/JavaScript/Anonymous_Functions
If you are not familiar with JS syntax try to take online course to get your head around it.
JAVASCRIPT COURSE:
http://www.codecademy.com/en/tracks/javascript
Google for more. ;)

Steam API Get SteamID using Javascript

Been running into what appears to be the Same Origin Policy which is causing quite some headache!
To cut to the chase, I am essentially trying to acquire a user's steam64id when only supplied their username.
For example, my username: "Emperor_Jordan" I would go to:
http://steamcommunity.com/id/emperor_jordan?xml=1
And the steamid I need is right at the top. So I figured I would use JQuery Ajax to acquire this and parse out the id I need for later usage (steamapi usage requires the steam64id) as follows. Here is a snippet of the code in question:
$.ajax({
url: "http://steamcommunity.com/id/emperor_jordan/?xml=1",
datatype: "xml",
complete: function()
{
alert(this.url)
},
success: parse
});
function parse(xml)
{
alert("parsing");
_steamID = $(xml).find("steamID64").text();
}
The problem here is while I do get the alert for the completion, I never see "parsing". Ever. It never gets that callback, which leads me to believe I am running into the SOP (same origin policy).
Am I approaching this the wrong way, is there a workaround?
Thanks!
Correct. You are running into the same-origin policy:
XMLHttpRequest cannot load http://steamcommunity.com/id/emperor_jordan/?xml=1. Origin http://fiddle.jshell.net is not allowed by Access-Control-Allow-Origin.
and it looks like Steam does not offer a cross-origin solution like JSONP. That means you're back to the old-but-reliable solution: fetch the data on your server, not in the browser.
Some relevant feedback on the Steam Web API: https://developer.valvesoftware.com/wiki/Steam_Web_API/Feedback#API_Considerations_for_Web_Developers
You need to create a proxy server in Heroku in order to get the data. Cors is restricting us to call the data directly to our browser not server to server interaction. So we need a proxy server to send the requests and receive the data on our behalf. It's working for me.
Thanks in advance.

How can I get time from another server using AJAX?

I need to get time from some online source - NTP server, JSON time server, or maybe event just an HTTP Header. I don't care about precision, but I do need to get time from an online source. I don't have access to any servers so I can't write any server side code.
I can't do this using HTTP Request to get the header since I guess it would be violating the same origin policy.
And I can't seem to find a way of doing it that does not involve some level of PHP or other languages - I can only use HTML/CSS/JS...nothing else!
Any ideas?
$.ajax({
url: 'http://timeapi.org/utc/now.json',
dataType: 'jsonp'
})
.done(function(response) {
// response = {"dateString":"2012-03-06T02:18:25+00:00"}
console.log(response.dateString);// "2012-03-06T02:18:25+00:00"
});
JavaScript has a same origin policy. You can not make calls to another domain. If you could do it, I could access your email, bank accounts, etc.
If the browser supports CORS and the 3rd party has it enabled, you are in luck. Other than that, you should look at a JSONP service that can give you the info.
Javascript has built-in functionality for date and time. You can get the current time like so:
var now = new Date();
document.write(now);
You can read more about using Javascript's Date object here http://www.w3schools.com/js/js_obj_date.asp

JQuery ajax cross domain call and permission issue

I have this polling script to check if a text file is created on the server. Works great locally, but fails when the file is on a different domain. How would i rewrite this for cross domain support?
$.ajax({
url: 'http://blah.mydomain.com/test.txt',
type: "GET",
success: function(result) {
//Success!
window.location.replace(Successful.aspx');
},
error: function(request, status, error) {
setTimeout("VerifyStatus(" + pollingInterval + ")");
}
});
EDIT:
I ended up using YQL to solve the cross domain issue and although it works, YQL is really slow that's adding quite a bit of performance overhead. Can anyone suggest a better solution for cross domain JQuery calls?
Set the dataType to "JSONP" on your $.ajax() call. You'll have to make sure the response is properly formatted for it to work. Wikipedia has a good section on JSONP.
Ajax doesn't go cross domain. Your best bet is to create a php page on the local domain that does the check, and go to -that- with your ajax call.
To get cross-domain AJAX via jQuery, you might want to check this out:
http://github.com/jamespadolsey/jQuery-Plugins/tree/master/cross-domain-ajax/
Almost modern browsers are now supporting cross domain with CORS protocol, so you can use Ajax jQuery to do your job without editing anything in your script code. The change is into your server, you need to enable your server with CORS. It's just the job with adding header fields in each responses to client to support CORS protocol. See an implementation example here.
http://zhentao-li.blogspot.com/2013/06/example-for-enabling-cors-support-in.html

Categories

Resources