I am attempting to process a user-uploaded file in javascript and then upload the file to the server. Once the processing is complete, I want the upload to work as it would have if I had not interrupted it with javascript. That is, I want to send a POST request to something like "receive_file.php" where the form validation, move_uploaded_file(), and a "successful upload" message to the user will occur. I have tried this in jquery, and I get an UPLOAD_ERR_NO_FILE from php:
function upload(file) {
var form = $("<form/>", {
enctype: "multipart/form-data",
method: "POST",
action: "/path/to/recieve_file.php"
});
form.append($("<input/>", {
type: "file",
name: "audio_file",
value: file
}));
form.submit();
}
As far as I can tell, its not possible to write to an input type="file", only read from it. Still haven't found a great answer for this one, but what I have settled on is overwriting the current document with the response from an ajax request like so:
var fd = new FormData();
fd.append("audio_file", file);
var xhr = new XMLHttpRequest();
xhr.open('POST', 'recieve.php', true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
document.open();
document.write(xhr.response); // just overwrite the whole current document with "recieve.php"
document.close();
}
};
xhr.send(fd);
Related
I have configured my TinyMCE to use images_upload_url and images_upload_handler to post to a selected image to a server-side page which saves the image to a location on my server. In addition, this server-side page also saves the filename of the image as a record within a database.
I then have another server-side page which reads the database and constructs a JSON list of the images that have been uploaded. This JSON data is then pulled into my Tinymce instance using image_list, so that I can easily reuse previously uploaded images as opposed to having to reupload the same image more than once.
The specific lines of my tiny.init() are:
image_list: 'processes/image-list.php',
image_class_list: [
{title: 'None', value: ''},
{title: 'Full width image', value: 'img-responsive'}
],
images_upload_url: 'processes/upload-image.php',
images_upload_handler: function (blobInfo, success, failure) {
var xhr, formData;
xhr = new XMLHttpRequest();
xhr.withCredentials = false;
xhr.open('POST', 'processes/upload-image-free.asp');
xhr.onload = function() {
var json;
if (xhr.status != 200) {
failure('HTTP Error: ' + xhr.status);
return;
}
json = JSON.parse(xhr.responseText);
if (!json || typeof json.location != 'string') {
failure('Invalid JSON: ' + xhr.responseText);
return;
}
success(json.location);
};
formData = new FormData();
formData.append('file', blobInfo.blob(), blobInfo.filename());
xhr.send(formData);
},
image_dimensions: false,
All of this works as expected.
What I would like to do is also save a description of the image to the database so this can be outputted as the title within the JSON data of previously uploaded images.
As the upload feature only allows an image to be selected from a file system I cannot utilise the upload feature:
So I thought I could utilise the alternate description field of the image feature/modal but this would have to be done via a JavaScript triggered event that is triggered upon submitting the image feature/modal, that takes the content in the alternative description input field and POST this to a serverside page that can update the database.
Unless there is another way does anybody know how I can target the 'click' on the 'save' button within the image feature to extract the alternate description before the image feature/modal disappears and extract the input field content?
From there I should be able to work out how to get this to a server-side page to update the database.
Many thanks in advance
I have managed to resolve this so posting a solution to help others - though this is more than a hack.
Firstly on my form page after the tiny.init is loaded I am using the following:
document.addEventListener('keyup', logKey);
function logKey(e) {
labels = document.querySelectorAll(".tox-label");
for (i = 0; i < labels.length; ++i) {
if (labels[i].textContent == "Alternative description"){
imageDescription = document.getElementById(labels[i].htmlFor).value;
}
}
};
This loops through all the elements (labels in this case) which have a class of .toxlabel and if the textContent matches "Alternative description" then to capture the value in in a variable called 'imageDescription'.
Then within my tiny.init I have the following:
editor.on('ExecCommand', function(e) {
if (e.command == "mceUpdateImage"){
var http = new XMLHttpRequest();
var params = encodeURI('desc=' + imageDescription);
http.open('POST', 'processes/upload-image-description.asp', true);
http.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
http.onreadystatechange = function() {//Call a function when the state changes.
if(http.readyState == 4 && http.status == 200) {
console.log(http.responseText);
}
}
http.send(params);
}
});
This code is actioned upon the mceUpdateImage modal closing, it takes the value stored within the imageDescription variable and posts it to a server-side page which updates the database.
I am sure there are cleaner ways but they would require more of a TinyMce understanding.
I am loading my table on document.ready() from a json file as follows
document load....
$(document).ready(function () {
getSummaryData(function (data1) {
var dataarray=new Array();
dataarray.push(data1);
$('#summaryTable').DataTable({
data: dataarray,
"columns": [
---
---
and retrieving the data from a file as follows
function getSummaryData(cb_func1) {
$.ajax({
url: "data/summary.json",
success: cb_func1
});
console.log(cb_func1)
}
This was essentially loading dummy data so i could I could figure out how to load the table correctly etc. This works fine.
It does following
1. page loads
2. reads data from file
3. populates table
In reality, the data will not be loaded from file but will be returned from xhr response but I am unable to figure out
how to wire it all together. The use case is
POST a file via XMLHttpRequest
Get response
populate table (same data format as file)
I will post the file as follows...
<script>
var form = document.getElementById('form');
var fileSelect = document.getElementById('select');
var uploadButton = document.getElementById('upload');
---
form.onsubmit = function(event) {
event.preventDefault();
---
---
var xhr = new XMLHttpRequest();
// Open the connection.
xhr.open('POST', 'localhost/uploader', true);
// handler on response
xhr.onload = function () {
if (xhr.status === 200) {
console.log("resp: "+xhr);
console.log("resptxt: "+xhr.responseText);
//somehow load table with xhr.responseText
} else {
alert('ooops');
}
};
// Send the Data.
xhr.send(formData);
So ideally I need one empty row in the table or similar until someone uploads a file and then the table gets populated with the response.
Any help much appreciated.
var xhr1 = new XMLHttpRequest();
xhr1.open('POST', "youruploadserver.com/whatever", true);
xhr1.onreadystatechange = function() {
if (this.status == 200 && this.readyState == 4) {
console.log(this.responseText);
dostuff = this.responseText;
};//end onreadystate
xhr1.send();
It looks mostly correct, You want the this.readyState == 4 in there. what is your question, how to populate a table from the response?
That also depends on how you are going to send the data and how the server is going to parse the data, looks like you want to use a json format which is smart. JSON.stringify(formdata) before you send it and then make sure your server parses it as a json object Using body-parser depending on what server you are using. and then you JSON.stringify() the object to send it back.
I'm fairly new to JS (& SO), but I have a webpage where I upload a file sometimes as big as 500mb. The user takes a file from their OS and I want to preview the file in a <pre> </pre> box before sending off to a http endpoint, but for performance reasons I'd rather not read the entire file and then slice out the first few lines.
If possible, I'd like to just read the first few lines instead. This could be the first few bytes too if that's easier, there's no strict cut off point.
Currently I do this to read the file:
if (file) {
var reader = new FileReader();
reader.readAsText(file, "UTF-8");
reader.onload = function (evt) {
document.getElementById("mailingFileText").innerHTML = evt.target.result;
};
}
...and I set it inside this:
<pre class="pre-scrollable" style="white-space: pre-wrap;">
<p id="mailingFileText"></p>
</pre>
But this isn't overly feasible for really large files. Can anyone help?
Make sure to test your site
Code a Example:
jQuery
$(window).ready(function() {
$.ajax({
url: './wiki-stevenjobs.txt',
type: 'GET',
contentType: 'text/txt; charset=UTF-8',
success: function(data) {
$('p#mailingFileText').html(data);
},
error: function(err){
$('p#mailingFileText').html(err);
}
});
});
OR
Javascript Pure:
var xhr = new XMLHttpRequest();
xhr.open("GET", "./wiki-stevenjobs.txt", true);
xhr.setRequestHeader("Content-Type", "text/txt; charset=UTF-8");
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
document.getElementById("mailingFileText").innerHTML = xhr.response;
}
};
xhr.send();
500mb too much more 10minutes is depend a server, is best 10mb minimum.
I want to get an audio file from a server in JavaScript and play it. But the ajax call in my code never seems to callback, and I am also unsure whether I handle the audio in JavaScript correctly.
The following PHP file returns the audio file on the server:
<?php
header('Access-Control-Allow-Origin: *');
$name = './audiofiles/audio.wav';
$fp = fopen($name, 'rb');
header("Content-Type: binary");
header("Content-Length: " . filesize($name));
fpassthru($fp);
exit;
?>
The script is called from JavaScript using ajax and the returned audio data is replayed in the browser (at least thats what should happen):
function playSample(e,q) {
console.log("requesting audio from server")
$.ajax({
url: "https://audioserver.com/getaudio.php",
type: "GET",
dataType: "arraybuffer",
processData: false,
success: function(result){
console.log("received audio, starting to play now")
var buffers = result;
var newSource = audioContext.createBufferSource();
var newBuffer = audioContext.createBuffer( 2, buffers[0].length, 16000 );
newBuffer.getChannelData(0).set(buffers[0]);
newSource.buffer = newBuffer;
newSource.connect( audioContext.destination );
newSource.start(0);
}
});
}
What am I doing wrong here?
jQuery ajax does not support typed responses, so you're going to get text as result in your success callback.
You can use bare XMLHTTPRequest to get a binary response
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if (this.readyState == 4 && this.status == 200){
//this.response is the array buffer for you to manipulate
}
}
xhr.open('GET', 'https://audioserver.com/getaudio.php');
xhr.responseType = 'arraybuffer';
xhr.send();
There is also a plugin that patches jquery to support it https://github.com/acigna/jquery-ajax-native
Also your your audio processing code looks incorrect. buffers[0] doesn't make sense since an arraybuffer doesn't have numeric properties
I want to upload a file trough a XMLHttpRequest. i have looked everywhere for examples and found quite a few. But i cant figer out what it is i am doing wrong. This is my code. The function is triggerd when a button is pressed. It not wrapped in from tags
function upl_kost() {
var url = "proces_data.php?ref=upload_kost";
var hr;
var file = document.getElementById("file_kost");
var formData = new FormData();
formData.append("upload", file.files[0]);
if (window.XMLHttpRequest) {
hr=new XMLHttpRequest();
} else {
hr=new ActiveXObject("Microsoft.XMLHTTP");
}
hr.open("POST", url, true);
hr.setRequestHeader("Content-type", "multipart/form-data");
hr.onreadystatechange = function() {
if(hr.readyState == 4 && hr.status == 200) {
var return_data = hr.responseText;
alert(return_data);
}
}
hr.send(formData);
}
and this function catches it.
if($_GET['ref'] == 'upload_kost') {
var_dump($_FILES);
}
My problem is that the $_FILES stays empty. When i look at the file.files variable in the js its loaded with the data from the file that i am trying to upload.
Thanks!
Reduce your JavaScript down to minimum required for this, then add in some helpful messages you can look in your console for
function upl_kost() {
var xhr = new XMLHttpRequest(),
url = 'proces_data.php?ref=upload_kost',
fd = new FormData(),
elm = document.getElementById('file_kost');
// debug <input>
if (!elm)
console.warn('Element not found');
else if (!(elm instanceof HTMLInputElement))
console.warn('Element not an <input>');
else if (!elm.files || elm.files.length === 0)
console.warn('<input> has no files');
else
console.info('<input> looks okay');
// end debug <input>
fd.append('upload', elm.files[0]);
xhr.addEventListener('load', function () {
console.log('Response:', this.responseText);
});
xhr.open('POST', url);
xhr.send(fd);
}
If you're still having a problem, it may be server-side, e.g. are you performing a redirect before trying to access $_FILES?
Your problem is that you're setting the content type of the request
hr.setRequestHeader("Content-type", "multipart/form-data");
If you ever saw a multipart/formdata post you'll notice the content type header has a boundary
Content-Type: multipart/form-data; boundary=----webko2354645675756
which is missing from your code.
If you do not set the content type header the browser will correctly set it and the required boundary. This will allow the server to properly parse the request body.