I’ve recently tried to upload a file from a client to a server and faced the problem of cross-domain. Indeed, uploading is done with ajax, to be able to analyze the response. So, I had to solve 2 problems: uploading with ajax and cross-domain.
Concerning cross-domain, I’ve found many different solutions but none of them really fit my need since I needed to add informations in the header. (I think there were other reasons, but cannot remember). I find it easier to make a two step upload. First, I upload the file to my simple PushState server, then the server upload the file to the other website. This server is built using NodeJs, express and request. Upload is made with request and its form parameter which allows us to do multipart/form-data.
Here is the server:
var express = require('express'); var request = require('request'); var fs = require('fs'); var app = express(); app.use(express.logger()); app.use(express.bodyParser({uploadDir:'./tmp'})); app.use(app.router); app.use(express.static('./public')); app.use(function(req, res) { fs.createReadStream('./public/index.html').pipe(res); }); app.post('/upload', function(req, res, next) { //Configure the request var opts = { url: "http://your/url", method: "POST", headers: { login: "yourLogin", password: "yourPassword" } }; var x = request(opts); var form = x.form(); //Optionnal: Add a name and a type to form var fileName = req.files.file.name.split('.'); form.append('name', fileName[0]); form.append('type', fileName[fileName.length - 1]); //Add file to the request form.append('file', fs.createReadStream(req.files.file.path)); //Pipe response from website to the client x.pipe(res); }); app.listen(4242, function() { console.log('Server running!'); });
Uploading with ajax is done thank to jquery.iframe-transport (just add it in your code).
Concerning ajax, code is really simple:
$.ajax({ url: "http://localhost:4242/upload", type: 'POST', files: $('.fileUpload'), iframe: true, success: function(data, textStatus, jqXHR) { //Do whatever you want with the response }, error: function(err) { console.error(err); console.log("Error while uploading the document. :/"); } });
The html behind:
<form enctype="multipart/form-data"> <input class='fileUpload' type="file" name="file"/> </form>
In this case, I listen for the event change input.fileUpload which indicates that a file has been chosen and then, call a function executing the ajax part. It would also be possible to react on click on a button.
Other solutions concerning cross-domain: http://stackoverflow.com/questions/3076414/ways-to-circumvent-the-same-origin-policy https://github.com/blueimp/jQuery-File-Upload/wiki/Cross-domain-uploads