jQuery cross domain image upload - javascript

Ok, so basically.
I inject some javascript code into a web page and it uploads an image on that page to another server.
Now I have it working when I run it on my domain (of course), but I need to post the multipart/form-data request to a PHP file that I do not own.
Since it is a upload and not a simple request to just get data, I cannot use jsonp in the initial call since the response would not be in json.
Using James Padolsey's cross domain script, I am able to do $.get and $.post request across domains, but since I am using $.ajax it does not work.
He uses the Yahoo Query Language to acomplish this
This is basically how I am making the request
$.ajax({
url: 'http://website.com/upload.php',
type: 'POST',
contentType:'multipart/form-data',
data: postData,
success: successCallback,
error : function(XMLHttpRequest, textStatus, errorThrown) {
console.log('Error');
}
});
I want to make it completely JavaScript based to avoid making my server do the request.
So to re-cap, I can get the image bytes and make the request with javascript. But so far I cannot make it cross domain since I am $.ajax to set the content Type to "multipart/form-data".
Is there another way to make the request cross domain with or without the YQL?
Making the request with an iframe will not work since the domain of the iframe would change and I would not have access to the response.

This is a well known and difficult problem for web development, know as the Same Origin Policy
Javascript prevents access to most methods and properties to pages across different origins. The term "origin" is defined using the domain name, application layer protocol, and (in most browsers) port number of the HTML document running the script. Two resources are considered to be of the same origin if and only if all these values are exactly the same.
There are several ways around this.
Create your own proxy
Create a page that simply forwards the request to the other server, and returns its response
or, Use Apache's rules to form a proxy (see above link)
Use someone else's proxy
For GET requests which are typical Use YQL to access yahoo's proxy
For POST requests, if the 3rd party supports Open Data Tables
or, Use some other public proxy
See if the 3rd party conforms to the CORS specification
Cross domain POST query using Cross-Origin Resource Sharing getting no data back
If you are willing to allow a little flash on your page, try flXHR
it claims to implement the exact XHR api and also has a jquery plugin
These are pretty much your only options

Related

Cross domain request with JSON response

I am trying cross domain request from my js file.
First,I was trying JSONP but my target domain URL is not support it. It return plain JSON object.
I am authorize person to access my target domain URL. but i can not modify it as per JSONP response.
SO how can i get JSON response from my target domain URL?
Without modifying a bit the server side there is not much you can do. The general policy is to not to allow cross domain requests.
There are few things worth mentioning though:
Try changing the server side so it will support JSONP.
If the HTTP response contains Access-Control-Allow-Origin header then you can communicate with it with normal AJAX. This feature is supported in modern browsers only. Check this out for more info.
You can do the cross domain requests with Flash and/or WebSockets. However server does have to support them.
I have always done it with jsonp, by passing a callback b/c services return json, if call back is passed then it will wrap all json in callback else they will simple return json.
But in your case
You can look up with this article
http://www.webdevdoor.com/jquery/cross-domain-browser-json-ajax/
Don't know what type application you are developing. But in ASP.NET you can do it by using a proxy page
These links may be helpful:
http://www.codeproject.com/Articles/667611/ASP-NET-Proxy-Page-Used-for-Cross-Domain-Requests
http://encosia.com/use-asp-nets-httphandler-to-bridge-the-cross-domain-gap/
https://gist.github.com/jkresner/3982746

REST request from app works, but not from javascript

I'm building an app that has to get and set data at a remote web service through requests. When I use the jQuery GET request it works fine, I can request data from the service without any problems, but when I use PUT I get some erros:
OPTIONS http://myurl.com 501 (Unsupported method
('OPTIONS'))
OPTIONS http://myurl.com Origin null is not allowed by Access-Control-Allow-Origin.
I've tried almost anything to get this to work, but it won't work. I've download a chrome app called REST Console, which can make custom REST requests. The strange thing is that I can interact with my server over that app but not through my javascript!
This is the javascript:
$.ajax({
url: 'http://myurl.com',
type: 'PUT',
data: '<time>16:00</time>',
success: function(data) { alert(data); }
});
Could anybody tell me what is going on here?
First ensure you're serving the page that runs the script from a web server, not directly from the file system.
I'm guessing your service at http://myurl.com is at a different host name to the host name your page is being served from? For it to work in this case you need to implement HTTP headers to support Cross Origin Resource Sharing.
Your service at http://myurl.com needs to handle an HTTP OPTIONS request, the response to which should be a set of HTTP headers (with no content) as follows:
Access-Control-Allow-Origin: http://url-of-page-with-javascript/
Optionally you can also specify Access-Control-Allow-Credentials, Access-Control-Allow-Headers and Access-Control-Allow-Methods. See the full specification here.
You'll also need to add the same headers with the same values when your server responds to the PUT request - obviously the content will also be included with this response.

Make REST call in JavaScript without using JSON?

(extremely ignorant question, I freely admit)
I have a simple web page with a button and a label. When I click the button, I want to make a REST call to an entirely different domain (cross-domain, I know that much) and display the results (HTML) in the label.
With other APIs, I've played around with using JSON/P and adding a element on the fly, but this particular API doesn't support JSON so I'm not sure how to go about successfully getting through.
The code I have is:
function getESVData() {
$.get('http://www.esvapi.org/v2/rest/passageQuery?key=IP&passage=John+1', function (data) {
$('#bibleText').html(data);
app.showNotification("Note:", "Load performed.");
});
}
I get an "Access denied." Is there anyway to make this call successfully without JSON?
First off, JSON and JSONP are not the same. JSON is a way of representing information, and JSONP is a hack around the same-origin policy. JSONP works by requesting information from another domain, and that domain returns a script which calls a function (with the name you provided) with the information. You are indeed executing a script on your site that another domain gave to you, so you should trust this other domain.
Now when trying to make cross domain requests you basically have 3 options:
Use JSONP. This has limitations, including the fact that it only works for GET requests, and the server you are sending the request to has to support it.
Make a Cross Origin Resource Sharing (CORS) request. This also must be supported by the server you are sending the request to.
Set up a proxy on your own server. In this situation you set an endpoint on your site that simply relays requests. ie you request the information from your server, your server gets it from the other server and returns it to you.
For your situation, it the other server doesn't have support for other options, it seems like you will have to go with options 3.

How to do cross domain ajax in jQuery with dataType 'text'?

In my javacript function I call this ajax. It works fine but only when I access the web page from firebird server. I have the same code on my testing server. The ajax asks to download some files but only firebird server has its ip registers with our clients to be able to scp there. I need to do the same if I access the php files from testing server. All the servers are inside intranet.
is it possbile to use dataType text to do so?
do I need to do any changes on the server side?
ajax call:
url = "https://firebird"+path+"/tools.php?";
jQuery.ajax({
type: 'get',
dataType: 'text',
url: url,
data: {database: database_name, what: 'download', files: files, t: Math.random() },
success: function(data, textStatus){
document.getElementById("downloading").innerHTML+=data;
}
});
Update 1
My little web application restores databases so I can do my testing on them. Now I want to enhance it so I can connect to our customers and download a particular backup. Our customer allowed only firebird server to connect to their networks. But I have my own server dedicated to testing. So every time I want to download a database I need to connect firebird. The source of my web application and the folder with all backups are mounted into the same location on both servers firebird and testing. Right now my solution (for downloading) works but only from firebird. I work basically only testing server though.
Update 2
I make two ajax calls. One is pure jQuery call (I guess I can apply any solution to this one) and the other one is ajax call from jsTree. I created new question for that one. I seems to me that I have to go for #zzzz's option b).
To do cross domain requests, your options are fairly limited. As #Mrchief mentioned, you could do server side proxy and jsonp.
Another option is Cross-Origin Resource Sharing (CORS), a W3C working draft. Quoting from this blog post:
The basic idea behind CORS is to use custom HTTP headers to allow both
the browser and the server to know enough about each other to
determine if the request or response should succeed or fail.
For a simple request, one that uses either GET or POST with no custom
headers and whose body is text/plain, the request is sent with an
extra header called Origin. The Origin header contains the origin
(protocol, domain name, and port) of the requesting page so that the
server can easily determine whether or not it should serve a response.
You can find some live examples on this site.
You will need to make changes to the server side, to accept the CORS requests. Since you have control over the server, this shouldn't be a problem. Another downside with CORS is that, it might not be compatible with older browsers. So, if some of your essential audiences use incompatible browsers, the server side proxy may actually be a better option for you.
I just want to offer an alternative.
I am not too sure regarding your network setup, but if you have access to the DNS, maybe it would be easiest if you just give your servers some arbitrary subdomain of the same domain. Something like www.foo.com for the webfront and firebird.private.foo.com for the firebird server. This way, it becomes cross subdomain instead of cross domain. Then somewhere in your JavaScript on both pages,
document.domain = "foo.com";
This gentleman achieved this solution here.
You have the following options with you
a) You use jsonp type as your datatype but this involves making changes on the server side to pass the data back as json and not as txt.. this change might be as simple as
{
"text":<your current text json encoded>
}
and on your js side you use this as response.text; Having said that if you are getting the textis for you file from sm other domain I am not sure how easy it is for you to change the code.
b) The other option is you write a handler/end point on your server i.e within your domain that will make an HTTP request to this third domain gets the file and you send the file back to your client and effectively now your client talks to your domain only and you have control over everything. as most of yoyr questions are based on ruby here is an example:
req = Net::HTTP.get_response(URI.parse('http://www.domain.com/coupons.txt'))
#play = req.body
you can find more details about the same here.
Hope this helps.
Another idea is to use you web server as a proxy. You will need to consider the security implications for this route.

Sending POST message with AJAX Problem

I am currently trying to send a POST message which works fine except for the error that there are not correct credentials. However, after I add the credentials header, the message type is changed into OPTIONS and fails. I do not understand how adding a header causes the type to change to OPTIONS. Any help would be appreciated.
ajaxRequest = $j.ajax({
url: url,
type: 'POST',
beforeSend : function(req) {
req.setRequestHeader('Authorization', auth),
}
success: function(data, status) {
console.log("Success!!");
console.log(data);
console.log(status);
},
error: function(xhr, desc, err) {
console.log(xhr);
alert('fail')
console.log("Desc: " + desc + "\nErr:" + err);
}
});
EDIT: just to be more clear, I can literally go in and comment out the setRequestHeader function and it sends the message POST.
The problem you're encountering is because of cross-domain restrictions when using AJAX. When you try to set an authorization header, the browser issues what's known as a pre-flight request to see if the server will accept requests from this domain.
A pre-flight request is typically sent as an OPTIONS request. If the server you're invoking doesn't return an Access-Control-Allow-Origin header that matches your domain, the AJAX request is blocked.
There's more on this here: Cross-Origin Resource Sharing
"User agents can discover via a preflight request whether a cross-origin resource is prepared to accept requests, using a non-simple method, from a given origin."
I've run into the same problem- there are a few possible workarounds depending on your scenario.
If you have any way of setting the above mentioned header on the 3rd party server (some applications/services offer this) then that's probably the easiest way.
There's also a javascript library called EasyXDM that may work for you, but again, it will only be of use if you have access to the 3rd party server to upload a configuration file for this library.
Other options to investigate are PostMessage and Cross Domain Iframe communication. The latter is more of an old-school hack, the former is the recommended approach for newer browsers. It won't work for IE6/7.
The option we will probably end up using is a simple proxy- invoke our own server with the AJAX request, and on the server invoke the 3rd party server. This avoids the cross domain issue entirely, and has other advantages for our scenario.
I guess this is a problem in Internet Explorer. without explicitly telling the request-method (POST|GET) the request header doesn't contain the custom-header in IE, but it works in other browsers.
Yet try to post this in the bugs for jquery. Also try in other browsers.
Edit 1 : I saw this as a bug in jQuery 1.4.x .... I reported a bug report now.
The OPTIONS response happens when the server does not know how to respond to the ajax request.
I've seen it happen often when trying to post to a third-party domain (i.e. cross-site posting)
The OPTIONS method represents a request for information about the communication options available on the request/response chain identified by the Request-URI. This method allows the client to determine the options and/or requirements associated with a resource, or the capabilities of a server, without implying a resource action or initiating a resource retrieval.
Have you tried:
Having some sort of callback on the url that is being posted to?
Explicitly setting the headers (I'm assuming you're using PHP) on the url that is being posted to?

Categories

Resources