Get a file through AJAX with JQuery - javascript

I looked for an answer to my problem everywhere but I didn't found what I want to know.
Here is what I want to do:
I have an url of an image, pdf or html page from the same domain and from other domains too. Is it possible to "download" them with AJAX?
But I don't want to have them physically on my server or anywhere else, I just want to use them directly on my website without having to upload them again (to save time).
I'm also having some troubles doing "XMLHttpRequest.getAllResponseHeaders()" when the content comes from an other domain. I tried with multiples url. I received nothing: "". Is it normal?
Thank you for your help ! :)

Unfortunately it is impossible to make AJAX requests for resources on domains external to the website's host domain, edit: unless they implement a workaround, like CORS or JSONP. I recommend doing some reading on Cross Origin Resource Sharing for more details.
As for resources on the same domain, you'd be storing those on your server anyway - you'd have to, in fact, because by its very nature it would be a part of your site. If you describe what you're trying to implement specifically (perhaps post a jsfiddle with your code), we could find a solution to your specific use case. Hope this helps.

[...] image, pdf or html page [...]
The types of these requests are very different. What you mean with 'download' is a little ambigious. If you're requesting a file via AJAX, this loads the value into a variable. It doesn't save the file to your computer.
[...] I received nothing: "" Is it normal? [...]
Yes, if the remote server isn't the same as you're currently on (also the same port) and also doesn't support CORS (cross-domain requests), the result will be blank.
If it's not possible to alter the remote server's cross-domain policies [and you have the permission to use their services], you could write a PHP script on your server that acts as a proxy. But don't forget to secure it to prevent mis-use. Also keep in mind that such a script can raise your traffic dramatically, so this should only be "Plan B".

You certainly can fetch images and html pages with AJAX and display them on your webpages.
The issues you are having with the xmlHttpRequest.GetAllResponseHeaders is most likely caused by the same origin policy. The browser prohibits you from interacting with the loaded data from another domain.
The server you are fetching the data from has to explicitly indicate that it allows your domain to fetch and display his resources by setting the Access-Control-Allow-Origin response header to that of your domain.
A way arround this is by using a proxy and setting the header yourself.

The following boilerplate code ( basically taken from the jquery api page ) loads your gravatar image ( delivered in png format ) from the stackoverflow website into a callback parameter. As others have noted, the same origin policy applies to ajax requests ( The sample code therefore can onlybe successfully run from the stackoverflow site context, eg. by opening a js console on this page ).
$.ajax({
method: "GET"
, url: "https://www.gravatar.com/avatar/d85e0ad5243245aabe2d34a3c9a296a9?s=32&d=identicon&r=PG&f=1"
, cache: false
, beforeSend: function( xhr ) {
xhr.overrideMimeType( "text/plain; charset=x-user-defined" );
}
})
.done(function( data ) {
if ( console && console.log ) {
console.log( "Length of data:", data.length );
console.log( "Sample of data:", data.slice( 0, 100 ) );
}
});

Related

External file fail to load on 'load' function

I want to load content of external text file (demo.txt) in my div on button click.
Text file containes text 'Demo text.'
But it shows error
XMLHttpRequest cannot load file:///C:/Users/Tom/Desktop/jQuery%20thenewboston/76.)%20Load%20function/demo.txt. Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https, chrome-extension-resource.
on my browser console.
$(document).ready(function(){
$('#button_file').on('click',function(){
$('#load_html').load('demo.txt');
});
});
<button type="button" id="button_file">Load file</button>
<br />
<div id="load_html" >
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
I am a beginner in jquery , please comment below for any query.
You cannot get the result because the remote site doesn't have CORS enabled: If you look at the console, you'll see:
(Reason: CORS header 'Access-Control-Allow-Origin' missing).
You can bypass CORS by using something like anyorigin.com, i.e.:
$.getJSON('http://anyorigin.com/get/?url=http%3A//thenewboston....&callback=?', function(data){
$('#div-data').html(data.contents);
});
PS: If it's a local file, make sure you load it on the same address as the script, (localhost, 127.0.0.1, 192.168.1.1, etc...)
You are being restricted by HTTP access control (CORS). The file you are requesting asynchronously needs to be from the same domain or the domain you are accessing it from needs to allow your domain to access it. As you are using the file:/// protocol you need to allow it, so check out this if that's the way you wish to go.
Alternatively you can create a local web server to host your site an allow access to the file on the same domain.
In order to make this work you need to use a web server instead of using just clicking on the html file.
Check XAMPP
Unfortunately, Google Chrome doesn't allow cross-origin request although Firefox does.
Alternatively, if the text file is short you can store it in an object and place it wherever you like.
text_file = {
contents = 'content';
}
$('.button_class').on('click',function(){
$('.div').html(text_file.contents);
});
I would never suggest you use this but if it's a small project, a one page application that nobody will see the code to - desperate times call for desperate measures.
The best thing to do is to use XAMPP and PHP.
Load in from your database the content you would like to show.
You can read the PHP documentation or watch online tutorials , I personally suggest TheNewBoston PHP Tutorials with Alex Garrett

Externally load Json with jquery.getJSON

I don't know if this is a duplicate post or not, sorry if it is. I'm using jquery.getJSON to load a json on my server which works just fine. Although, if I try and load a json file on a different server it doesn't work. I know I don't have any code here (because there's not much point) but I just want to know if I'm using it wrong or if it isn't supposed to load external files. I'm using the iOS Safari browser if that effects anything.
EDIT: I've looked at the console (idk what the error thing really means, it's just red with an x by the url it's trying to get the json from) and it looks like it's not actually receiving the data. Plus, do remember I'm on iOS, not desktop so I couldn't look at the console in the "Develop tab :P
EDIT 2: Great! I think I got it working! http://skitty.xyz/getJSON/
You're most likely encountering a path issue; the purpose of $.getJSON is to acquire data via http GET request so yes, it is intended to work remotely. To diagnose your issue, make certain you can access the json file in your browser first: http://domain.com/my_data.json. If that works, use that as the URL you pass into $.getJSON:
$.getJSON( 'http://domain.com/my_data.json', function(data) {
// do something with your data
});
http://api.jquery.com/jquery.getjson/
jquery.getJSON uses ajax which is all about external resources. Here's a couple things to check for if it's not working on an external resource:
1: Is the path you specified correct? The usage is jquery.getJSON(path, callback). The path should be something you can just drop in your browser and see. If an incorrect path is your problem, you'll see a 404 in the console.
2: Is the resource http and your site https? Non-secure resources on secure pages will get blocked by browser security features. You'd see a error to this effect in the console.
3: Is CORS (Cross-origin resource sharing) enabled for your site on the external resource? Servers will sometimes use a whitelist of IPs and domains to determine what origins are allowed to make requests of it. You'd also see an error to this effect in the console.
There probably some other things to look for but this is where I'd start.
Also, by all means, use the debugging features of Safari to LQQK at the actual HTTP data-streams that are passing back-and-forth in response to what you're doing. (You might need to click on a preference to see the "Develop" menu, which will take you to "Show Web Inspector" and its Network tab.)
This approach will instantly answer many questions that a JavaScript-centered approach will not so-readily tell you. (And of course, you can look at the JavaScript console too ... and at the same time.) "The actual data streams, please." Safari will tell you "exactly what bytes" your app actually sent to the server, and "exactly what bytes" the server sent in return. "Priceless!™"
Are you saying you are using jquery ajax request to load some json data from a server?
check the "not working server" has the same end point as your server.
Check if the url you want to get data from is correct.
check if console logged any errors.
Also quote from http://api.jquery.com/jquery.getjson/
"Additional Notes:
Due to browser security restrictions, most "Ajax" requests are subject to the same origin policy; the request can not successfully retrieve data from a different domain, subdomain, port, or protocol.
Script and JSONP requests are not subject to the same origin policy restrictions."

AJAX request gets "No 'Access-Control-Allow-Origin' header is present on the requested resource" error

I attempt to send a GET request in a jQuery AJAX request.
$.ajax({
type: 'GET',
url: /* <the link as string> */,
dataType: 'text/html',
success: function() { alert("Success"); },
error: function() { alert("Error"); },
});
However, whatever I've tried, I got XMLHttpRequest cannot load <page>. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:7776' is therefore not allowed access.
I tried everything, from adding header : {} definitions to the AJAX request to setting dataType to JSONP, or even text/plain, using simple AJAX instead of jQuery, even downloading a plugin that enables CORS - but nothing could help.
And the same happens if I attempt to reach any other sites.
Any ideas for a proper and simple solution? Is there any at all?
This is by design. You can't make an arbitrary HTTP request to another server using XMLHttpRequest unless that server allows it by putting out an Access-Control-Allow-Origin header for the requesting host.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
You could retrieve it in a script tag (there isn't the same restriction on scripts and images and stylesheets), but unless the content returned is a script, it won't do you much good.
Here's a tutorial on CORS:
http://www.bennadel.com/blog/2327-cross-origin-resource-sharing-cors-ajax-requests-between-jquery-and-node-js.htm
This is all done to protect the end user. Assuming that an image is actually an image, a stylesheet is just a stylesheet and a script is just a script, requesting those resources from another server can't really do any harm.
But in general, cross-origin requests can do really bad things. Say that you, Zoltan, are using coolsharks.com. Say also that you are logged into mybank.com and there is a cookie for mybank.com in your browser. Now, suppose that coolsharks.com sends an AJAX request to mybank.com, asking to transfer all your money into another account. Because you have a mybank.com cookie stored, they successfully complete the request. And all of this happens without your knowledge, because no page reload occurred. This is the danger of allowing general cross-site AJAX requests.
If you want to perform cross-site requests, you have two options:
Get the server you are making the request to to either
a. Admit you by putting out a Access-Control-Allow-Origin header that includes you (or *)
b. Provide you with a JSONP API.
or
Write your own browser that doesn't follow the standards and has no restrictions.
In (1), you must have the cooperation of the server you are making requests to, and in (2), you must have control over the end user's browser. If you can't fulfill (1) or (2), you're pretty much out of luck.
However, there is a third option (pointed out by charlietfl). You can make the request from a server that you do control and then pass the result back to your page. E.g.
<script>
$.ajax({
type: 'GET',
url: '/proxyAjax.php?url=http%3A%2F%2Fstackoverflow.com%2F10m',
dataType: 'text/html',
success: function() { alert("Success"); },
error: function() { alert("Error"); }
});
</script>
And then on your server, at its most simple:
<?php
// proxyAjax.php
// ... validation of params
// and checking of url against whitelist would happen here ...
// assume that $url now contains "http://stackoverflow.com/10m"
echo file_get_contents($url);
Of course, this method may run into other issues:
Does the site you are a proxy for require the correct referrer or a certain IP address?
Do cookies need to be passed through to the target server?
Does your whitelist sufficiently protect you from making arbitrary requests?
Which headers (e.g. modify time, etc) will you be passing back to the browser as your server received them and which ones will you omit or change?
Will your server be implicated as having made a request that was unlawful (since you are acting as a proxy)?
I'm sure there are others. But if none of those issues prevent it, this third method could work quite well.
you can ask the developers of that domain if they would set the appropriate header for you, this restriction is only for javascript, basically you can request the ressource from your server with php or whatever and the javascript requests the data from your domain then
Old question, but I'm not seeing this solution, which worked for me, anywhere. So hoping this can be helpful for someone.
First, remember that it makes no sense to try modifying the headers of the request to get around a cross-origin resource request. If that were all it took, it would be easy for malicious users to then circumvent this security measure.
Cross-origin requests in this context are only possible if the partner site's server allows it through their response headers.
I got this to work in Django without any CORS middleware by setting the following headers on the response:
response["Access-Control-Allow-Origin"] = "requesting_site.com"
response["Access-Control-Allow-Methods"] = "GET"
response["Access-Control-Allow-Headers"] = "requesting_site.com"
Most answers on here seem to mention the first one, but not the second two. I've just confirmed they are all required. You'll want to modify as needed for your framework or request method (GET, POST, OPTION).
p.s. You can try "*" instead of "requesting_site.com" for initial development just to get it working, but it would be a security hole to allow every site access. Once working, you can restrict it for your requesting site only to make sure you don't have any formatting typos.

Unable to retrieve the result of a Perl script via Ajax (Same origin policy issue)

So, this Perl script:
http://hacheck.tel.fer.hr/xml.pl
will return a XML result based on the POST form-data that it receives.
I have a web-page on one of my domains (none of which are hacheck.tel.fer.hr) and I would like to use that Perl script via Ajax.
Now, the Same origin policy disallows me to send Ajax requests from my domain like so:
$.post('http://hacheck.tel.fer.hr/xml.pl', {'textarea': '...'}, function(data) {
// process data
});
The above code throws this error:
XMLHttpRequest cannot load
http://hacheck.tel.fer.hr/xml.pl.
Origin http://ecmazing.com is not
allowed by
Access-Control-Allow-Origin.
I would like to know what my options are (I would like to be able to use that Perl script). I know that placing my web-page onto the hacheck.tel.fer.hr domain would obviously solve my issue (and that may in fact be doable, but I'll have to contact the admin for that).
But are there any alternatives?
I've heard about CORS. Could it be used to solve my issue? If I understand correctly, with CORS you have to specify on the server that another domain is permitted, and than web-pages from that other domain can receive responses from your server (or something like that) :)?
I've heard about CORS. Could it be used to solve my issue?
Yes, but only in browsers that support it. The controller of hacheck.tel.fer.hr would have to set it up.
But are there any alternatives?
Proxy the request through your own server

Submit cross domain ajax POST request

I swear I saw an article about this at one point but can not find it...
How can I perform a jQuery ajax request of type POST on another domain? Must be accomplished without a proxy. Is this possible?
Yes you can POST all you want, even $.post() works...but you won't get a response back.
This works, the other domain will get the POST:
$.post("http://othersite.com/somePage.php", { thing: "value" }, function(data) {
//data will always be null
});
But the response, data in the above example, will be null due to the same-origin policy.
All the options I've experimented with:
1) PORK: http://www.schizofreend.nl/Pork.Iframe/Examples/ Creates an iframe and submits the post there, then reads the response. Still requires same base domain per
request (i.e. www.foo.com can request
data from www2.foo.com, but not from
www.google.com) . Also requires you to
fiddle with the document.domain
property, which causes adverse side
effects. And there's a pervasive problem in all the major browsers where reloading the page basically shuffles the cached contents of all iframes on the page if any of them are dynamically written. Your response data will show up in the box where an ad is supposed to be.
2) flxhr: http://flxhr.flensed.com/ Can even be used to mask jQuery's built-in ajax so you don't even notice it. Requires flash though, so iPhone is out
3) jsonp: Doesn't work if you're posting a lot of data. boo.
4) chunked jsonp: When your jsonp request is too big, break the query string up into manageable chunks and send multiple get requests. Reconstruct them on the server. This is helpful but breaks down if you're load balancing users between servers.
5) CORS: http://www.w3.org/TR/cors/ doesn't work in older browsers (IE7, IE6, Firefox 2, etc)
So we currently do the following algorithm:
If request is small enough, use JSONP
If not small enough, but user has flash, use FlXHR
Else use chunked JSONP
Spend one afternoon writing that up and you'll be able to use it for good. Adding CORS to our algorithm might be good for faster iPhone support.
If you have control over the code running at the other domain, just let it return an appropriate Access-Control-Allow-Origin header in the response. See also HTTP Access-Control at MDC.
If you want a fire and forget POST where you don't care about the response then just submit a form to a hidden iframe. This requires a Transitional Doctype.
<form method="POST" action="http://example.com/" target="name_of_iframe">
If you want to parse the response, then using a proxy if the only real option.
If you are desperate, and control the remote site, then you can:
Submit a form as above
Set a cookie in the response (which might be blocked before the iframe could cause the cookie to be considered '3rd party' (i.e. likely to be advertising tracking).
Wait long enough for the response to come back
Dynamically generate a script element with the src pointing to the remote site
Use JSON-P in the response and take advantage of the data previously stored in the cookie
This approach is subject to race conditions and generally ugly. Proxing the data through the current domain is a much better approach.
If you need to know that the POST was successful, and don't have control over the remote server:
$.ajax({
type:"POST",
url:"http://www.somesite.com/submit",
data:'firstname=test&lastname=person&email=test#test.com',
complete: function(response){
if(response.status == 0 && response.statusText == "success")
{
/* CORS POST was successful */
}
else
{
/* Show error message */
}
}
});
If there was a problem with the submission then response.statusText should equal "error".
Note: some remote servers will send the HTTP header Access-Control-Allow-Origin: *, which will result in a 200 OK HTTP status code response. In that case, ajax will execute the success handler, and this method is not needed. To look at the response just do console.log(JSON.stringify(response)); or use FireBug's 'Net' panel.

Categories