How to preview text excerpt from large file in Javascript - javascript

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.

Related

Corrupted .xlsx file from Flask web app and ajax POST request

I have a Flask web app with a URL route that receives a post request with some json, parses it to an .xlsx file, then returns the file with send_file().
Server side, I can see that the .xlsx file that is generated is correct but, once downloaded on the client side, the file is corrupted and can't be opened and is much larger than expected (201KB vs. 112KB).
I suspect it's some sort of encoding issue, but I've tried a whole bunch of stuff and can't make any headway. Can anyone help, please?
Flask route:
#app.route('/request/export_XLSX',methods=['POST'])
def request_export_XLSX():
json_model = json_util.loads(request.data.decode('ascii', 'ignore'))
xlsx_model = detox.xlsxFromJSONModel(json_model) # Returns file path
result = send_file(xlsx_model, as_attachment=True, attachment_filename=json_model['id']+'.xlsx', mimetype='application/vnd.ms-excel')
return result
JavaScript:
var exportModelExcel = function(){
var model = detox.fba.model
d3.selectAll('*').style("cursor","wait")
var modelJson = JSON.stringify(model)
$.ajax({
type: "POST",
url: "/request/export_XLSX",
data: modelJson,
success: function(d){
d3.selectAll('*').style("cursor","")
var blob = new Blob([d], {type: 'application/vnd.ms-excel'})
var link=document.createElement("a");
link.href=window.URL.createObjectURL(blob);
link.download=model.id+".xlsx";
link.click();
},
error: function(jqxhr,textStatus,errorThrown){
console.log("Error: " ,textStatus,errorThrown)
d3.selectAll('*').style("cursor","")
alert("There was an error exporting the model")
},
contentType: 'application/json',
responseType: 'blob',
processData: false,
});
}
Here's a link where you can see the good and bad .xlsx files: https://gofile.io/d/xywI1D
Well, I ended up ripping out the ajax and using an XMLHTTPRequest instead.
It works nicely and results in an uncorrupted .xlsx file. 🙂
var exportModelExcel = function(){
var model = detox.fba.model;
var modelJson = JSON.stringify(model);
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var downloadUrl = URL.createObjectURL(xhttp.response);
var a = document.createElement("a");
document.body.appendChild(a);
a.style = "display: none";
a.href = downloadUrl;
a.download = model.id+".xlsx";
a.click();
}
};
xhttp.open("POST", "/request/export_XLSX", true);
xhttp.setRequestHeader("Content-Type", "application/json");
xhttp.responseType = "blob";
xhttp.send(modelJson);
}

Ajax blob type recognition javascript

I'm using javascript to download multiple files from a webpage.
I'm using FileSaver.js to save the file and this method to download :
function downloadFile(url, success) {
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = "blob";
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
if (success) success(xhr.response);
}
};
xhr.send(null);
}
together I'm using it like that :
downloadFile(imgurl, function(blob) {
saveAs(blob, "image" + item + ".jpeg");
});
but the problem is im not sure what is the image/video type and the links arent specifying them. (cant take extention from url there's none)
My main issue is recognition between videos and images, probably mp4/png but I prefer being able to determine each file type so I can save it with its extention.
thanks in advance

Getting a file type from URL

I need To find out the file type from a url image located on my server without checking the extension, but I'm not sure how to do that without putting the image into an "input" like this:
<input type="file" id="upload_file" accept="image/*|audio/*|video/*"/>
<input type="submit" onclick="sumbit()"/>
<script type="text/javascript">
function sumbit(){
var file_Element = document.getElementById("upload_file")
alert(file_Element.files[0].type);
//alert: image/png
}
<script>
I understand that ".type" only work with a file object, so how do I turn the url image into an object like this image of google's logo: https://www.google.ca/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png.
Do I need to use a ajax/flilereader? if so, how?
Assuming your Content-Type HTTP headers are accurate, you can avoid downloading the whole file just to check the type by creating a HEAD request. Assuming you don't also need the whole file for something else, this could be a much-quicker operation, especially for large files.
Working Example:
var xhr = new XMLHttpRequest();
xhr.open('HEAD', 'https://crossorigin.me/http://placehold.it/350x150', true);
xhr.onload = function() {
var contentType = xhr.getResponseHeader('Content-Type');
console.log(contentType);
};
xhr.send();
Alternately, you can achieve a similar result with a regular GET request by calling abort on the AJAX request object before it loads the whole body (in any remotely recent browser anyway).
Alternate Working Example:
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://crossorigin.me/http://placehold.it/350x150', true);
xhr.onreadystatechange = function() {
// Wait for header to become available.
var contentType = xhr.getResponseHeader('Content-Type');
if (contentType) {
// Stop downloading, the headers are all we need.
xhr.abort();
console.log(contentType);
}
};
xhr.send();
The accept attribute value is not valid. There should be comma , instead of pipe | character separating MIME types.
You can use change event to check File object .type
<input type="file" id="upload_file" accept="image/*,audio/*,video/*"/>
<input type="submit" onclick="submit()"/>
<script type="text/javascript">
var elem = document.getElementById("upload_file");
elem.onchange = function(e) {
console.log(e.target.files[0].type)
}
function submit() {
if (elem.files.length) {
console.log(elem.files[0].type)
} else {
alert("no files selected")
}
}
</script>
Use XHR to download the file, and then use the Blob api to determine the mime type:
var xhr = new XMLHttpRequest();
xhr.open('GET', '/path/to/image.png', true);
xhr.responseType = 'blob';
xhr.onload = function(e) {
//Here's the type
console.log(xhr.response.type);
};
xhr.send();

Working with Computer Vision Thumbnails API repsonse data in JavaScript

I'm using the Microsoft Cognitive Computer Vision API (the thumbnails function).
I'm trying to use JavaScript and I cannot make sense of the response.
My entire HTML document with embedded JS code is as follows:
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
</head>
<body>
<button id="btn">Click here</button>
<p id="response">
<script type="text/javascript">
$('#btn').click(function () {
$.ajax({
url: "https://api.projectoxford.ai/vision/v1.0/generateThumbnail?width=100&height=100&smartCropping=true",
beforeSend: function (xhrObj) {
xhrObj.setRequestHeader("Content-Type", "application/json");
xhrObj.setRequestHeader("Ocp-Apim-Subscription-Key", "382f5abd65f74494935027f65a41a4bc");
},
type: "POST",
data: '{"url": "https://oxfordportal.blob.core.windows.net/emotion/recognition1.jpg"}'
})
.done(function (response) {
$("#response").text(response);
})
.fail(function (error) {
$("#response").text(error);
});
});
</script>
</body>
</html>
The response I'm getting does not appear to be JSON, it look like this:
How can I work with the response from this API such that I get the image as a base 64 string that I can set to be the src on an image element.
It will end up being something like this but I do not know how to get the <base64string> bit.
<img src="data:image/png;base64,<base64string>">
I've tried everything in the api test console at https://dev.projectoxford.ai/docs/services/56f91f2d778daf23d8ec6739/operations/56f91f2e778daf14a499e1fb/console and it seems to work fine.
I think the problem is that jQuery converts the argument passed to .done into a string – not sure how to stop it doing that. You could try converting that string back to a binary object but that doesn't feel right or you could work out how to get the raw response from jQuery.
I tried this using XMLHttpRequest (which works):
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
console.log(this.response, typeof this.response);
var response = document.querySelector('#response');
var img = new Image();
var url = window.URL || window.webkitURL;
img.src = url.createObjectURL(this.response);
response.appendChild(img);
}
}
xhr.open('POST', 'https://api.projectoxford.ai/vision/v1.0/generateThumbnail?width=5&height=5&smartCropping=true');
xhr.setRequestHeader("Content-Type", "application/json");
xhr.setRequestHeader("Ocp-Apim-Subscription-Key", "382f5abd65f74494935027f65a41a4bc");
xhr.responseType = 'blob';
xhr.send('{"url": "https://oxfordportal.blob.core.windows.net/emotion/recognition1.jpg"}');
The response from the service is a binary JPEG image, indicated by the response header "Content-Type: image/jpeg".
For advice on how to encode this as base64, and display it, you could look to these related answers:
Base64 encoding
Displaying an image from a web-service

Upload file after javascript processing, no ajax

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);

Categories