Skip to content

Instantly share code, notes, and snippets.

@kazupon
Last active December 11, 2015 05:58
Show Gist options
  • Save kazupon/4555747 to your computer and use it in GitHub Desktop.
Save kazupon/4555747 to your computer and use it in GitHub Desktop.
.DS_Store
*.swp
'use strict';
var express = require('express');
var http = require('http');
var path = require('path');
var log = console.log.bind(console);
var format = require('util').format;
var app = express();
app.configure(function(){
app.set('port', process.env.PORT || 3000);
app.set('views', './');
app.set('view engine', 'jade');
app.set('x-powered-by', false);
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
});
app.configure('development', function(){
app.use(express.errorHandler());
});
app.get('/', function (req, res) {
res.render('index', { title: 'backbone Data URL data POST sample' });
});
app.post('/upload', function (req, res) {
log(req.headers);
log(req.files);
res.json({ stat: 'ok' });
});
app.post('/save', function (req, res) {
log(req.headers);
log(req.files);
log(req.body);
res.json({ stat: 'ok', img: { id: 1 } });
});
app.post('/save2/', function (req, res) {
log(req.headers);
log(req.files);
log(req.body);
var res_format = '<html><title>RES</title><body>%s</body></html>';
res.header('mime-type', 'text/html'); // for iframe upload
res.header('content-type', 'text/html'); // for iframe upload
res.send(format(res_format, JSON.stringify({ stat: 'ok', img: { id: 1 } })));
});
if (require.main === module) {
http.createServer(app).listen(app.get('port'), function(){
log("Express server listening on port " + app.get('port'));
});
}
extends layout
block content
h1= title
form#uploadform.formcl(enctype="multipart/form-data", method="post", action="/upload", target="uploadframe")
input#imagefile(type="file", accept="image/*", name="imagefile")
input#uploadbutton(type="button", value="upload")
img#preview
input#savebutton(type="button", value="save")
input#savebuttonbyiframe(type="button", value="iframe")
script(src='/javascripts/main.js')
doctype 5
html
head
title= title
link(rel='stylesheet', href='/stylesheets/style.css')
script(src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js")
script(src="http://underscorejs.org/underscore-min.js")
script(src="http://backbonejs.org/backbone-min.js")
body
block content
(function () {
'use strict';
var log = console.log.bind(console);
var error = console.error.bind(console);
var content;
var fileSelected = function () {
var file = $('#imagefile').get(0).files[0];
var image_format = /^(image\/bmp|image\/gif|image\/jpeg|image\/png|image\/tiff)$/i;
log('image_format', file.type);
if (!image_format.test(file.type)) {
alert('invalid image format');
return;
}
var $preview = $('#preview');
var reader = new FileReader();
//reader.readAsDataURL(file);
reader.readAsBinaryString(file);
reader.onload = function (e) {
$preview.attr('src', e.target.result);
log('target', e.target);
content = reader.result;
};
};
var startUpload = function () {
var form_data = new FormData($('#uploadform').get(0));
var xhr = new XMLHttpRequest();
log('form_data', form_data);
xhr.upload.addEventListener('progress', function () {
log('progress', arguments);
}, false);
xhr.addEventListener('load', function () {
log('load', arguments);
}, false);
xhr.addEventListener('error', function () {
error('error', arguments);
}, false);
xhr.addEventListener('abort', function () {
log('abort', arguments);
}, false);
xhr.open('POST', '/upload');
xhr.send(form_data);
};
XMLHttpRequest.prototype.sendAsBinary = function (datastr) {
function byteValue (x) {
return x.charCodeAt(0) & 0xff;
}
var ords = Array.prototype.map.call(datastr, byteValue);
var ui8a = new Uint8Array(ords);
this.send(ui8a.buffer);
};
var startBackboneSave = function () {
var ImageModel = Backbone.Model.extend({
urlRoot: '/save/',
sync: function (method, model, opts) {
log('sync', method, model, opts);
var org_success = opts.success;
var org_error = opts.error;
if (method === 'create') {
var boundary = 'boundary';
var crlf = '\r\n';
var body = '--' + boundary + crlf;
body += 'Content-Disposition: form-data; name=' + '"imagefile"' + '; filename="' + this.get('filename') + '"' + crlf;
body += 'Content-Type: image/png' + crlf + crlf;
body += this.get('data') + crlf;
body += '--' + boundary + '--' + crlf;
var xhr = new XMLHttpRequest();
opts.success = function () {
log('load', arguments);
org_success && org_success(model, JSON.parse(xhr.responseText), opts);
model.trigger('sync', model, JSON.parse(xhr.responseText), opts);
};
xhr.addEventListener('load', opts.success, false);
opts.error = function () {
error('error', arguments);
org_error && org_error(model, xhr, opts);
model.trigger('error', model, xhr, opts);
};
xhr.addEventListener('error', opts.error, false);
xhr.open("POST", this.urlRoot, true);
var contentType = "multipart/form-data; boundary=" + boundary;
xhr.setRequestHeader("Content-Type", contentType);
xhr.sendAsBinary(body);
model.trigger('request', model, xhr, opts);
return xhr;
}
},
parse: function (res) {
log('parse', res);
var ret = {};
this.set({ id: res.img.id });
return ret;
}
});
var img = new ImageModel({
filename: $('#imagefile').get(0).files[0].name,
data: $('#preview').attr('src')
});
img.on('request', function () {
log('request event');
});
img.on('sync', function () {
log('sync event');
});
img.save({}, {
success: function () {
log('save success');
},
error: function () {
error('save error');
}
});
};
var startBackboneSaveByIFrame = function () {
var ImageModel = Backbone.Model.extend({
initialize: function (attr, opts) {
this.$form = opts.form;
this.$form.attr('files', opts.files);
this.$form.attr('action', this.urlRoot);
},
urlRoot: '/save2/',
sync: function (method, model, opts) {
log('sync', method, model, opts);
var self = this;
var org_success = opts.success;
var org_error = opts.error;
if (method === 'create') {
var $iframe = $('<iframe></iframe>');
$iframe.attr({
name: this.$form.attr('target'),
style: 'display:none;'
});
$('body').append($iframe);
$('<input />').attr('type', 'hidden')
.attr('name', 'hoge')
.attr('value', this.get('hoge'))
.appendTo(this.$form);
this.$form.one('submit', function () {
$iframe.one('load', function () {
var $doc = $iframe.contents();
var res = $doc.find('body').text();
if (!res || res === '') {
org_error && org_error(model, self.$form, opts);
return;
}
var json = null;
setTimeout(function () {
try {
json = JSON.parse(res);
org_success && org_success(model, json, opts);
model.trigger('sync', model, json, opts);
} catch (e) {
org_error && org_error(model, self.$form, opts);
model.trigger('error', model, self.$form, opts);
} finally {
$iframe.remove();
}
}, 0);
});
}).submit();
model.trigger('request', model, this.$form, opts);
}
return;
},
parse: function (res) {
log('parse', res);
var ret = {};
this.set({ id: res.img.id });
return ret;
}
});
var img = new ImageModel({
hoge: 'hoge'
}, { form: $('.formcl') });
img.save({}, {
success: function (model, res, opts) {
log('save success', model, res);
},
error: function () {
error('save error');
}
});
};
$('#imagefile').on('change', function () {
fileSelected();
});
$('#uploadbutton').on('click', function () {
startUpload();
});
$('#savebutton').on('click', function () {
startBackboneSave();
});
$('#savebuttonbyiframe').on('click', function () {
startBackboneSaveByIFrame();
});
})();
{
"name": "application-name",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "node app"
},
"dependencies": {
"express": "3.0.6",
"jade": "*"
}
}
body {
padding: 50px;
font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;
}
a {
color: #00B7FF;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment