I'm using sockjs-0.3.4.
Before change page structure, it worked normally.
However after changing some stuff. abrubtly ws.onmessage function is beginning not to called.
I checked the connection with server by looking into devtools.
It looks like getting data from the server.
Please help me to know what's the point to check out.
enter image description here
var statusWatcher = {
curPage:"",
ws: null,
wsBaseUrl :null,
uid: null,
init : function(url ){
if(statusWatcher.ws != null) return;
console.log(statusWatcher.ws);
console.log("wsBaseUrl:"+url)
statusWatcher.wsBaseUrl = url;
var browserSupport = ("WebSocket" in window)? true: false;
if(browserSupport){
statusWatcher.start();
}else{
console.log("WebSocket is Not supported by your Web Browser!");
}
//log.eventHandler(1);
},
start : function(){
baseWsURL = statusWatcher.wsBaseUrl+"/statusCheck?&uid="+statusWatcher.uid;
console.log("web socket baseurl:"+baseWsURL);
try{
statusWatcher.ws = new WebSocket(baseWsURL);
} catch (e){
console.log(e);
}
statusWatcher.ws.onopen = function() {
console.log("web socket Opened! ");
};
statusWatcher.ws.onclose = function() {
console.log("web syslog socket Closed! ");
};
statusWatcher.ws = function(err) {
console.log("web syslog socket Error: " + err);
};
statusWatcher.ws.onmessage = function(evt) {
console.log("get message...");
//console.log("page:"+curPage);
var data = evt.data;
console.log(data);
var msg;
if(curPage =="main") return;
var e = JSON.parse(data);
if(e.status =="COMPLETE"){
$("#" + e.groupId).text("complete");
$("#" + e.groupId).removeClass('run error');
$("#" + e.groupId).addClass('complete');
statusWatcher.updateScoreState(e.groupId, "COMPLETE", e.topRplRate,e.topKwdRate);
}else if(e.status == "ERROR"){
$("#" + e.groupId).text("error");
$("#" + e.groupId).removeClass('run complete');
$("#" + e.groupId).addClass('error');
statusWatcher.updateScoreState(e.groupId, "ERROR");
}else{
$("#" + e.groupId).html("running("+e.progress+"/"+e.total+")");
$("#" + e.groupId).removeClass('error complete');
$("#" + e.groupId).addClass('run');
statusWatcher.updateScoreState(e.groupId, "RUNNING");
}
};
},
}
}
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<script src="<c:url value="js/fileuploadMain/statusWatcher.js"/>"></script>
</head>
<body>
<!--header-->
<c:import url="/WEB-INF/jsp/fileupload/header.jsp" />
<!--contents-->
<div class="contents">
<div class="container" id="container">
</div>
</div>
<script>
$(document).ready(function() {
var nice = $("html").niceScroll(); // The document page (body)
$(".select-items").niceScroll({
zindex: "auto",boxzoom:false
});
$("#container").load("group.do");
calaendar.init();
var wsBaseUrl = "ws://"+document.location.host+"<c:out value="${pageContext.request.contextPath}"/>";
statusWatcher.init(wsBaseUrl);
});
</script>
</body>
</html>
statusWatcher.ws = function(err) {
console.log("web syslog socket Error: " + err);
};
I changed upper source code to the next.. Maybe I remove the function name mistakenly..
statusWatcher.ws.onerror = function(err) {
console.log("web syslog socket Error: " + err);
};
Related
Hey Guys,
I have a problem to show my picture on my Page.
I dont know how to set the right path to show my picture.
I use socket.io and express. The Page is running on a Localhost Server
this is my code to show the picture but it doesnt works.
img src="uploads/images.png"
On the server-side i did this "app.use(express.static('public'));" to make it public. But it doesnt work, can someone help me ?
What is the right path?
My Folder structure is this
Folder structure
Server-side:
var app = require('express')();
var express = require('express');
var upload = require('express-fileupload');
var http = require('http').Server(app);
var io = require('socket.io')(http);
var multer = require('multer');
var fs = require('fs');
app.use(upload());
app.use(express.static('public'));
var users = {};
var allUsers = [];
function actualTime(){
var d = new Date();
return d.toLocaleTimeString();}
http.listen(3000, function(){
console.log('listening on *:3000');
});
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
io.on('connection', function(socket){
app.post('/upload',function(req,res){
console.log(req.files);
if(req.files.upfile){
var file = req.files.upfile,
name = file.name,
type = file.mimetype;
var uploadpath = __dirname + '/uploads/' + name;
file.mv(uploadpath,function(err){
if(err){
console.log("File Upload Failed",name,err);
res.send("Error Occured!")
}
else {
console.log("File Uploaded",name);
console.log("guckmal");
io.emit('file', name);
res.send('sasa');
}
});
}
else {
res.send("No File selected !");
res.end();
};
})
socket.on('username', function(data,callback){
if(data in users || data.length<=2){
callback(false);
}else{
callback(true);
socket.nickname = data;
users[socket.nickname] = socket;
// to get a message for all users who are not in the priavte chat
allUsers.push(""+socket.nickname);
for(var test=0; test<allUsers.length;test++){
console.log(allUsers[test]);
users[allUsers[test]].emit('usernames', {list:Object.keys(users), nick: allUsers[test]});
}
io.emit('chat message',{msg:"joined the Chatroom", nick:socket.nickname, time:actualTime()});
}
});
socket.on('chat message', function(data, callback){
console.log(socket.nickname);
console.log('User: ' + socket.nickname + ' message: ' + data);
var msg = data.trim();
if(msg.substr(0,3)=== '/w '){
console.log("private chat");
msg= msg.substr(3);
var temp = msg.indexOf(' ');
if(temp !== -1){
console.log("private chat stap 2");
var name = msg.substring(0,temp);
var msg = msg.substring(temp+1);
if(name in users){
console.log("private chat stap 3");
users[name].emit('private chat', {msg:msg, nick:socket.nickname, time:actualTime()});
for(var i=0; i<allUsers.length;i++){
if((name !==allUsers[i])){
if(allUsers[i] !== socket.nickname){
users[allUsers[i]].emit('private chat',{msg:"private message was send from "+socket.nickname+" to "+name, nick:socket.nickname, time:actualTime()});
}else{
users[socket.nickname].emit('private chat',{msg:"you send a private messgae to "+name, nick:"chat", time:actualTime()});
}
}
}
}else{
callback(' user name doesnt exist');
}
}else{
callback('Error! Please enter a message');
}
}else{
io.emit('chat message', {msg:msg, nick:socket.nickname, time:actualTime()});
}
});
socket.on('disconnect', function(data){
delete users[socket.nickname];
io.emit('chat message',{msg:"leaved the Chatroom", nick:socket.nickname, time:actualTime()});
io.sockets.emit('usernames', {list:Object.keys(users)});
});
});
Client-side:
$(function () {
var socket = io();
$('#loginForm').submit(function(e){
e.preventDefault(); // prevents page reloading
socket.emit('username', $('#u').val(), function(data,callback){
if(data){
$('#nickWrap').hide();
$('#contentWrap').show();
}else if(($('#u').val()).length<=2){
document.getElementById("u").value="";
document.getElementById("u").placeholder ="Sorry but Username length is less then three :(";
}else{
document.getElementById("u").value="";
document.getElementById("u").placeholder ="Sorry but Username already taken :(";
}
});
});
$('#chatForm').submit(function(e){
e.preventDefault(); // prevents page reloading
if(privateUsers.length>0){
for(var i=0;i<privateUsers.length;i++){
socket.emit('chat message','/w '+ privateUsers[i] +' '+ $('#m').val(), function(data){
// add stuff later
$('#messages').append($('<li>').text(data.time + " " + data.nick +': '+ data.msg ));
});
}
}else{
socket.emit('chat message', $('#m').val(), function(data){
// add stuff later
$('#messages').append($('<li>').text(data.time + " " + data.nick+': '+ data.msg ));
});
}
$('#m').val('');
return false;
});
socket.on('chat message', function(data){
$('#messages').append($('<li>').text(data.time + " " + data.nick +': '+ data.msg ));
});
socket.on('file', function(data){
var img = document.getElementById('bild');
images.push[data];
var name = data;
console.log(name);
$('#messages').append('<li><img src="uploads/images.png" />'+ '</li>');
img.setAttribute('src','data:image/jpeg;base64,' + window.btoa(images));
});
socket.on('private chat', function(data){
$('#messages').append($('<li>').text(data.time + " " + data.nick +': '+ data.msg ));
});
socket.on('usernames', function(socket, data){
console.log("2222222222");
// to get a massage for all users who are not in the priavte chat
console.log(socket.nick);
socketName = socket.nick;
});
socket.on('usernames', function(data){
document.getElementById("userList").innerHTML = "";
var temp;
var indexTemp;
var me= "";
var sortData = [];
for(var i=0;i<data.list.length;i++){
if(data.nick === data.list[i]){
indexTemp = i;
/* temp = data.list[i];
indexTemp =i;
data.list[i]= "Ich";*/
me ="My Name: ";
}
}
// sort list
sortData.push(data.list[indexTemp]);
for(var l=0; l<data.list.length;l++){
if(indexTemp !=l){
sortData.push(data.list[l]);
}
}
for(var i =0; i<sortData.length;i++){
if(i==0){
$('#userList').append('<li style="list-style:none "><buttonid="'+sortData[i]+'" onclick='+'"addUsers()"'+
' style="width: 100%; background: rgb(130, 224, 255); border: none; padding:10%; margin-bottom:2%; "'+'>'+"My Name: "+ sortData[i]
+'</button></li>');
//data.list[i]= temp;
}else{
$('#userList').append('<li style="list-style:none "><button id="'+sortData[i]+'" onclick='+'"addUsers(\''+sortData[i]+'\')"'+
' style="width: 100%; background: rgb(130, 224, 255); border: none; padding:10%; margin-bottom:2%; "'+'>'+ sortData[i]
+'</button></li>');
}
}
// }
});
});
function addUsers(name){
if(privateUsers.length==0){
console.log("erstes objekt");
document.getElementById(name).style.background = "rgb(1, 254, 185)";
privateUsers.push(name);
}else{
for(var i=0;i<privateUsers.length;i++){
if(name==privateUsers[i]){
console.log("gel�scht");
document.getElementById(name).style.background = "rgb(130, 224, 255)";
privateUsers.splice(i,1);
return;
}
}
console.log("drinnen");
document.getElementById(name).style.background = "rgb(1, 254, 185)";
privateUsers.push(name);
}
}
I have an issue where I am trying to pass my file information in query parameter form to the route that I have set up to upload my AWS file and then return the url. The issue I am running into is that the form is located within the view file accessed with the /create/comment route and prepended to all of my routes is /app. In my XMLHttpRequest I am requesting /app/sign and the file query parameters, but for some reason it keeps prepending this with /app/create or /app/create/app/sign, which is why I have 404 error. Is there a way a specific method to prevent the prepending of /app/create?
Error function at xhr.send();
function sign_request(file, done) {
var xhr = new XMLHttpRequest();
console.log(xhr);
console.log(file);
xhr.open("GET", "app/sign?file_name=" + file.name + "&file_type=" + file.type);
xhr.onreadystatechange = function() {
if(xhr.readyState === 4 && xhr.status === 200) {
var response = JSON.parse(xhr.responseText);
console.log(response);
done(response);
}
};
xhr.send();
};
Error Message:
comment:139 GET http://localhost:3000/app/create/app/sign?file_name=File-name.png&file_type=image/png 404 (Not Found)
Here is my route setup:
var express = require('express');
var router = express.Router();
router.use('/app');
var config = require(path.resolve(__dirname, '..', '..','./config/config.js'));
var models = require('../models/db-index');
var fs = require('fs');
var aws = require('aws-sdk');
/*==== /SIGN ====*/
router.get('/sign', function(req, res){
aws.config.update({accessKeyId: config.awsAccessKeyId, secretAccessKey: config.awsSecretAccessKey});
var s3 = new aws.S3()
var options = {
Bucket: config.awsBucket,
Region: 'us-east-1',
Key: req.query.file_name,
Expires: 60,
ContentType: req.query.file_type,
ACL: 'public-read'
}
s3.getSignedUrl('putObject', options, function(err, data){
if(err) return res.send('Error with S3')
res.json({
signed_request: data,
url: 'https://s3.amazonaws.com/' + S3_BUCKET + '/' + req.query.file_name
});
});
});
router.get('/create/comment',function(req, res){
models.DiscoverySource.findAll({
where: {
organizationId: req.user.organizationId
}, attributes: ['discoverySourceName']
}).then(function(discoverySource){
res.render('pages/app/comment-create.hbs',{
discoverySource: discoverySource
});
});
});
Form (Accessed at /app/create/comment):
<!DOCTYPE html>
<head>
{{> app/app-head}}
</head>
<body>
{{> app/app-navigation}}
<div class="container">
<div class="col-md-12">
<div class="row-form-container">
<label for="report-link">File Attachment:</label>
<input type="file" name="fileAttachment" id="image">
<img id="preview">
</div>
</div>
<script type="text/javascript">
function upload(file, signed_request, url, done) {
var xhr = new XMLHttpRequest();
xhr.open("PUT", signed_request);
xhr.setRequestHeader('x-amz-acl', 'public-read');
xhr.onload = function() {
if (xhr.status === 200) {
done();
};
};
xhr.send(file);
}
function sign_request(file, done) {
console.log('work please');
var xhr = new XMLHttpRequest();
console.log(xhr);
console.log(file);
xhr.open("GET", "app/sign?file_name=" + file.name + "&file_type=" + file.type);
xhr.onreadystatechange = function() {
if(xhr.readyState === 4 && xhr.status === 200) {
var response = JSON.parse(xhr.responseText);
console.log(response);
done(response);
}
};
xhr.send();
};
document.getElementById("image").onchange = function() {
var file = document.getElementById("image").files[0]
if (!file) return
sign_request(file, function(response) {
upload(file, response.signed_request, response.url, function() {
document.getElementById("preview").src = response.url
});
});
};
</script>
</body>
Adding a / before app/sign when you send a request will prevent the prepending of current subpath.
Try:
xhr.open("GET", "/app/sign?file_name=" + file.name + "&file_type=" + file.type);
I'm trying to keep subscribed to blockchain.info websocket api for new blocks. I basically took the code off http://www.websocket.org/echo.html and plugged in blockchain.info parameters. It works, but I'm finding that after a while it will automatically disconnect. How do I keep the session alive?
<!DOCTYPE html>
<meta charset="utf-8" />
<title>WebSocket Test</title>
<script language="javascript" type="text/javascript">
var wsUri = "wss://ws.blockchain.info/inv";
var output;
function init()
{
output = document.getElementById("output");
testWebSocket();
}
function testWebSocket()
{
websocket = new WebSocket(wsUri);
websocket.onopen = function(evt) { onOpen(evt) };
websocket.onclose = function(evt) { onClose(evt) };
websocket.onmessage = function(evt) { onMessage(evt) };
websocket.onerror = function(evt) { onError(evt) };
}
function onOpen(evt)
{
writeToScreen("CONNECTED");
doSend("{\"op\":\"blocks_sub\"}");
}
function onClose(evt)
{
writeToScreen("DISCONNECTED");
}
function onMessage(evt)
{
writeToScreen('<span style="color: blue;">RESPONSE: ' + evt.data+'</span>');
//websocket.close();
}
function onError(evt)
{
writeToScreen('<span style="color: red;">ERROR:</span> ' + evt.data);
}
function doSend(message)
{
writeToScreen("SENT: " + message);
websocket.send(message);
}
function writeToScreen(message)
{
var pre = document.createElement("p");
pre.style.wordWrap = "break-word";
pre.innerHTML = message;
output.appendChild(pre);
}
window.addEventListener("load", init, false);
</script>
<h2>WebSocket Test</h2>
<div id="output"></div>
I just tested this, and it seems to work:
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<script>
$(document).ready
(
function(){
initWebSocket();
}
);
</script>
<script language="javascript" type="text/javascript">
function initWebSocket()
{
// init blockchain websocket (activity, blocks)
var blockchain = new WebSocket('ws://ws.blockchain.info:8335/inv');
blockchain.onerror = function (error){ console.log('connection.onerror',error); };
blockchain.onopen = function ()
{
blockchain.send( JSON.stringify( {"op":"unconfirmed_sub"} ) ); // subscribe to uncofirmed activity
};
blockchain.onmessage = function (message)
{
var response = JSON.parse(message.data);
var date = new Date(0);
date.setUTCSeconds( response.x.time );
if( response.op == "utx")
{
var amount = 0;
for(var i=0;i<response.x.out.length;i++)
amount += response.x.out[i].value;
// amount is in satoshi
// 1 BTC = 100,000,000 Satoshi (https://en.bitcoin.it/wiki/activity)
response.amount = amount / 100000000;
}
console.log( response.op, response );
};
}
Largely taken from here: http://bl.ocks.org/npedrini/6030317
I am using HTML5's FileSystem API With Worklight to create cache files JSON format , I created to file without any problem , the problem is when I try to add some text to the created file , I used fileWriter but it doesn't write any thing .
this is the update function that I developed :
function update(fileName){
function onInitFs(fs) {
fs.root.getFile(fileName, {create: true}, function(fileEntry) {
// Create a FileWriter object for our FileEntry .
fileEntry.createWriter(function(fileWriter) {
fileWriter.onwriteend = function(e) {
console.log('Write completed.');
};
fileWriter.onerror = function(e) {
console.log('Write failed: ' + e.toString());
};
// Create a new Blob and write it to log.txt.
var blob = new Blob(['Lorem Ipsum'], {type: 'text/plain'});
fileWriter.write(blob);
}, errorHandler);
}, errorHandler);
}
window.requestFileSystem(window.PERSISTENT, 1024*1024, onInitFs, errorHandler);
function errorHandler(e) {
var msg = '';
switch (e.code) {
case FileError.QUOTA_EXCEEDED_ERR:
msg = 'QUOTA_EXCEEDED_ERR';
break;
case FileError.NOT_FOUND_ERR:
msg = 'NOT_FOUND_ERR';
break;
case FileError.SECURITY_ERR:
msg = 'SECURITY_ERR';
break;
case FileError.INVALID_MODIFICATION_ERR:
msg = 'INVALID_MODIFICATION_ERR';
break;
case FileError.INVALID_STATE_ERR:
msg = 'INVALID_STATE_ERR';
break;
default:
msg = 'Unknown Error';
break;
};
document.querySelector('#example-list-fs-ul').innerHTML = 'Error: ' + msg;
}
}
This is the read function to show the content of the file and it return a blank String :
function read(fileName){
function onInitFs(fs) {
fs.root.getFile(fileName, {}, function(fileEntry) {
// Get a File object representing the file,
// then use FileReader to read its contents.
fileEntry.file(function(file) {
var reader = new FileReader();
reader.onloadend = function(e) {
alert(this.result);
};
reader.readAsText(file);
}, errorHandler);
}, errorHandler);
}
window.requestFileSystem(window.PERSISTENT, 1024*1024, onInitFs, errorHandler);
}
Any one have any Idea how to fix this and how to successfully write and read from the file ?
Thank You
I think it would be better to use some of the Worklight features designed specifically for the purpose you are trying to achieve, like:
Encrypted cache
JSONStore
Here is a sample that allows to create/edit/read/delete a simple text file.
Hope this helps.
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<title>CordovaApp</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=0">
<!--
<link rel="shortcut icon" href="images/favicon.png">
<link rel="apple-touch-icon" href="images/apple-touch-icon.png">
-->
<link rel="stylesheet" href="css/main.css">
<script>window.$ = window.jQuery = WLJQ;</script>
<script type="text/javascript" charset="utf-8">
/**
* Function called when page has finished loading.
*/
function init(){
console.log("onDeviceReady");
}
onWLReady = function() {
// Wait for PhoneGap to load
document.addEventListener("deviceready", init, false);
}
function createFile() {
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0,
function(fileSystem) {
fileSystem.root.getFile("readme.txt", {create: true, exclusive: false},
function(fileEntry) {
fileEntry.createWriter(
function(writer) {
writer.onwriteend = function(evt) {
log("File created...");
};
writer.onwritestart = function(evt){
log("onwritestart");
};
writer.onwrite = function(evt){
log("onwrite");
};
writer.onerror = function(evt){
log("onerror");
};
writer.write("File created at: " + new Date().toLocaleString());
},
fail);
}
, fail);
},
fail);
}
function editFile() {
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0,
function(fileSystem) {
fileSystem.root.getFile("readme.txt", {create: false, exclusive: false},
function(fileEntry) {
fileEntry.createWriter(
function(writer) {
writer.onwriteend = function(evt) {
log("File edited");
};
writer.onwritestart = function(evt){
log("onwritestart");
};
writer.onwrite = function(evt){
log("onwrite");
};
writer.onerror = function(evt){
log("onerror");
};
writer.seek(writer.length);
writer.write("<br>File edited at: " + new Date().toLocaleString());
},
fail);
}
, fail);
},
fail);
}
function readFile() {
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0,
function(fileSystem) {
fileSystem.root.getFile("readme.txt", {
create : false
},
function(fileEntry){
fileEntry.file(function(file) {
readDataUrl(file);
readAsText(file);
},
fail);
},
fail);
}, fail);
}
function readDataUrl(file){
var reader = new FileReader();
log("readDataUrl...");
reader.onloadstart = function(evt){
log("onloadstart: " + evt.target.result);
};
reader.onload = function(evt){
log("onload: " + evt.target.result);
};
reader.onloadend = function(evt){
log("onloadend: " + evt.target.result);
};
reader.onerror = function(evt){
log("onerror: " + evt.target.result);
};
reader.readAsDataURL(file);
reader.abort();
}
function readAsText(file){
var reader = new FileReader();
log("readAsText...");
reader.onloadstart = function(evt){
log("onloadstart: " + evt.target.result);
};
reader.onload = function(evt){
log("onload: " + evt.target.result);
};
reader.onloadend = function(evt){
log("onloadend: " + evt.target.result);
};
reader.onerror = function(evt){
log("onerror: " + evt.target.result);
};
reader.readAsText(file);
}
function deleteFile() {
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0,
function(fileSystem) {
fileSystem.root.getFile("readme.txt", {
create : false
},
function(fileEntry){
fileEntry.remove(function() {log("File deleted.");
},
fail);
},
fail);
}, fail);
}
function fail(error){
var msg = error;
switch(error.code)
{
case FileError.NOT_FOUND_ERR:
msg = "File Not Found";
break;
case FileError.SECURITY_ERR:
msg = "Security Error";
break;
case FileError.ABORT_ERR:
msg = "Abort error";
break;
case FileError.NOT_READABLE_ERR:
msg = "Not Readable";
break;
case FileError.ENCODING_ERR:
msg = "Encoding Error";
break;
case FileError.NO_MODIFICATION_ALLOWED_ERR:
msg = "No Modification Allowed";
break;
case FileError.INVALID_STATE_ERR:
msg = "Invalid State";
break;
case FileError.SYNTAX_ERR:
msg = "Syntax Error";
break;
case FileError.INVALID_MODIFICATION_ERR:
msg = "Invalid Modification Error";
break;
case FileError.QUOTA_EXCEEDED_ERR:
msg = "Quota Exceeded";
break;
case FileError.TYPE_MISMATCH_ERR:
msg = "Type Mismatch Error";
break;
case FileError.PATH_EXISTS_ERR:
msg = "Path Already Exists Error";
break;
}
log("fail: "+ msg);
}
function log(info){
document.getElementById('log').innerHTML += "<br>" + info;
}
function clearLog(info){
document.getElementById('log').innerHTML = "";
}
</script>
</head>
<body style="display: none;">
<!--application UI goes here-->
<div>
<button onclick="createFile();">Create File</button><br>
<button onclick="editFile();">Edit File</button><br>
<button onclick="readFile();">Read File</button><br>
<button onclick="deleteFile();">Delete File</button><br>
<button onclick="clearLog();">Clear Log</button><br>
</div>
<script src="js/initOptions.js"></script>
<script src="js/main.js"></script>
<script src="js/messages.js"></script>
<div><u><b>Log:</b></u></div>
<div id=log></div>
</body>
</html>
Note that the Javascript methods should better be in js/main.js instead of being defined in the html file. It was simply easier for me to provide a working sample as a single file.
I need to test various web services which are posts that take an uploaded file as the content of the body. To do this I'd like to do quick tests using ajax call. I found the following page which describes how to do this:
http://www.captain.at/ajax-file-upload.php
However, it requires that the page have "UniversalXPConnect" privileges in firefox.
How do I enable that privilege? I tried editing prefs.js and adding:
user_pref("capability.principal.foo.id", "http://localhost:8080/access/index.html");
user_pref("capability.principal.foo.granted", "UniversalXPConnect");
which should give access to the page http://localhost:8080/access/index.html. But, it doesn't seem to work.
Improving on panzi's answer, you can use the FormData object to send files with Ajax in a very simple manner:
<html>
<head>
<title>HTML5 File API</title>
</head>
<script type="text/javascript">
// <!--
// See: https://developer.mozilla.org/En/XMLHttpRequest/Using_XMLHttpRequest#Using_FormData_objects
function upload() {
var uploadRequest = new XMLHttpRequest,
uploadForm = document.getElementById('file_upload');
function transferProgress(progressEvent) {
/*Executes For each update of the progress of the Ajax transfer.*/
// show progress bar or something....
}
function transferComplete() {
/*Executes when the transfer is complete.*/
//Do something like show a nice message...
}
function transferFailed() {
/*Executes when the transfer fails.*/
alert('Upload failed!');
}
function transferCanceled() {
/*Executes when the transfer is canceled.*/
alert('Upload canceled!');
}
uploadRequest.upload.addEventListener('progress', transferProgress, false);
//uploadRequest.upload.addEventListener('load', transferComplete, false); // transfer complete, but this doesn't mean a response from the server has been received.
uploadRequest.addEventListener('load', transferComplete, false); // ajax request complete, response from the server has been received and all has been processed.
uploadRequest.upload.addEventListener('error', transferFailed, false);
uploadRequest.upload.addEventListener('abort', transferCanceled, false);
uploadRequest.open('POST', action, true);
uploadRequest.send(new FormData(uploadForm));
}
// -->
</script>
<body>
<form id="file_upload" enctype="multipart/form-data">
<input type="text" id="text" value="blah blah blah"/>
<input type="file" onchange="upload();"/>
</form>
</body>
</html>
If the user specifies the file you don't need UniversalXPConnect. The HTML5 File API is enough:
<html>
<head>
<title>HTML5 File API</title>
</head>
<script type="text/javascript">
// <!--
// See: http://dev.w3.org/2006/webapi/FileAPI/
function upload (input) {
for (var i = 0; i < input.files.length; ++ i) {
// makes multiple uploads
uploadFile(input.files[i]);
}
}
function uploadFile (file) {
var reader = new FileReader();
reader.onprogress = function (event) {
var percent = 100 * event.loaded / event.total;
// TODO: display progress
};
reader.onerror = function (event) {
// display error
alert(errorMessage(reader.error)+': '+file.name);
};
reader.onload = function (event) {
if (reader.error) {
// display error
alert(errorMessage(reader.error)+': '+file.name);
}
else {
// You could also use reader.readAsBinaryString(file)
// and the mozilla specific function call btoa(reader.result).
// For more mozilla specific stuff (e.g. sending data as binary)
// see: https://developer.mozilla.org/en/using_xmlhttprequest
var data = reader.result.substring(reader.result.search(',')+1);
var text = document.getElementById('text').value;
var request = new XMLHttpRequest();
var boundaryString = guid();
var boundary = '--' + boundaryString;
while (text.search(boundary) != -1) {
boundaryString = guid();
boundary = '--' + boundaryString;
}
var requestbody = boundary + '\n' +
'Content-Disposition: form-data; name="mytext"\n' +
'\n' +
text +
'\n' +
boundary + '\n' +
'Content-Disposition: form-data; name="myfile"; filename="' +
file.name.replace(/"/g, '') + '"\n' +
'Content-Type: application/octet-stream\n' +
'Content-Transfer-Encoding: base64\n' +
'\n' +
data + '\n' +
boundary;
request.onreadystatechange = function () {
if (request.readyState == 4) {
if (request.status == 200) {
alert('Result: ' + request.responseText);
}
else {
alert(
'Error "' + request.statusText + '" occured while uploading: ' +
file.name);
}
}
};
/* a non-standard variant (still supported by many browsers) would be:
request.onuploadprogress = function () {
// possibly only mozilla, but awesome! upload progress!
var percent = 100 * event.loaded / event.total;
// TODO: display progress
};
request.onload = function () {
if (request.status == 200) {
alert('Result: ' + request.responseText);
}
else {
alert(
'Error "' + request.statusText + '" occured while uploading: ' +
file.name);
}
};
request.onerror = function () {
alert(
'There was a problem with the request when uploading file: ' +
file.name);
};
*/
request.open('POST', 'post.php', true);
request.setRequestHeader('Content-type', 'multipart/form-data; boundary="' +
boundaryString + '"');
request.setRequestHeader('Connection', 'close');
request.setRequestHeader('Content-Length', requestbody.length);
request.send(requestbody);
}
};
reader.readAsDataURL(file);
// there would also be:
// reader.readAsBinaryString(file);
// reader.readAsText(file, 'UTF-8');
// reader.readAsArrayBuffer(file);
}
function errorMessage (error) {
switch (error.code) {
case FileError.ABORT_ERR:
return 'Aborted';
case FileError.ENCODING_ERR:
return 'Encoding Error';
case FileError.NOT_FOUND_ERR:
return 'File not found';
case FileError.NOT_READABLE_ERR:
return 'File is not readable';
case FileError.NO_MODIFICATION_ALLOWED_ERR:
return 'File is not writeable';
case FileError.SECURITY_ERR:
return 'Security Error';
default:
return 'Unknown error code: ' + error.code;
}
}
// from: https://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript
function S4() {
return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
}
function guid() {
return (S4()+S4()+"-"+S4()+"-"+S4()+"-"+S4()+"-"+S4()+S4()+S4());
}
// -->
</script>
<body>
<input type="text" id="text" value="My text.."/>
<input type="file" onchange="upload(this);"/>
</body>
</html>
Still, I would recommend to use an iframe, because it is best supported by all browsers:
Is it possible to use Ajax to do file upload?