Gmail like file upload with jQuery - php

I would like to upload files just like google mail does. I would want to use jQuery and PHP to do it is there anyway of getting the progressbar etc.?
Here I added a video of how google does it. http://dl.getdropbox.com/u/5910/Jing/2009-04-02_1948.swf
No flash, no perl or cgi please..
I guess I can live without the progressbar now I am actually searching for information about jquery plugins or just what things I would need to look at

It is weird that people say that gmail doesn't use flash, when you can plainly see the swf file in the gmail interface. Try right clicking on "Attach a file". It is what allows the multiple uploads at once among other things.

The easiest would be to use SWFUpload, it's a small button written in Flash, with all the hooks to drive it in JS. Very easy to use and works well with PHP
but, if you really want it to be pure JS, you'll need some help from the server. specifically, you'll need to start the upload, and periodically query the server about how's it going. unfortunately, PHP upload handling doesn't get any notification until after the download finishes. you'd have to replace it with something else. there are a few pure JS uploaders that include sample Perl server code just because of that.
IOW: JS and PHP don't (fully) cut it. either add flash to the client, or a better upload handler at the server.

in my opinion an excellent article on this topic:
http://robertnyman.com/html5/fileapi-upload/fileapi-upload.html
unfortunately support is lacking for IE and Opera, but hopefully this will change.

Uploadify is another swf (sorry) upload button that uses jquery. Same idea as what Javier mentioned.

PHP doesn't support reporting of upload progress directly. So there is no way of reading the upload status back. However, there is a patch that might work. I haven't tried though.

GMail uses Flash to upload the file in the background. SWFUpload is an open source project that foes something similar.

...gmail uses an iFrame that has style display:hidden; then when you upload on the form, it then sends the iFrame to the upload url. There is no flash involved at all. The only thing Google does with flash on Gmail is just making noises for chats. And you have to allow that in settings. They don't really use flash too much just because it is pretty bad as far as memory and cpu usage. Javascript can do anything flash can do (albiet with a lot more code in some cases) but Javascript, in 99% of cases is much faster, and better memory-wise.

Maybe you could use PlUpload. It has support for a lot of types and is highly customizable. You can check out the demos on the website. On the homepage it also shows what it supports on the homepage and has a fallback mechanism.
http://www.plupload.com/
Edit: It is available as a jQuery plugin.

SWFUpload is gud and compatible with all type of web applications

About Ajax not supporting binary data while form submission.. there is a workaround; if you are jQuery then you can use this Form Plugin (from malsup) here at http://www.malsup.com/jquery/form/. I have been using it for years...
Also plupload seems promising.. thumbs up for that ;) i must say its a bit bulky!!!

In 2018, a website using plain JavaScript can upload files like Google Mail does for mail attachments. A single click can bring up the web browser's file explorer dialog. A separate Submit button is not needed to start the upload. The trick is to use a hidden HTML <input type="file"> element.
Example HTML and JavaScript:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>File Upload</title>
<!-- Demo a button to upload files from a local computer to a web server. -->
</head>
<body>
<input type="file" id="inputFileElement" multiple style="display:none">
<button id="fileSelectButton">Select some files</button>
<script>
const fileSelectButton = document.getElementById("fileSelectButton");
const inputFileElement = document.getElementById("inputFileElement");
// When the user presses the upload button, simulate a click on the
// hidden <input type="file"> element so the web browser will show its
// file selection dialog.
fileSelectButton.addEventListener("click", function (e) {
if (inputFileElement) {
inputFileElement.click();
}
}, false);
// When the user selects one or more files on the local host,
// upload each file to the web server.
inputFileElement.addEventListener("change", handleFiles, false);
function handleFiles() {
const fileList = inputFileElement.files;
const numFiles = fileList.length;
for (let i = 0; i < numFiles; i++) {
const file = fileList[i];
console.log("Starting to upload " + file.name);
sendFile(file);
}
}
// Asynchronously read and upload a file.
function sendFile(file) {
const uri ="serverUpload.php";
const xhr = new XMLHttpRequest();
const fd = new FormData();
xhr.open("POST", uri, true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
console.log("Finished uploading: " + xhr.responseText); // handle response.
}
};
fd.append('myFile', file);
// Initiate a multipart/form-data upload
xhr.send(fd);
}
</script>
</body>
</html>
PHP code:
<?php
if (isset($_FILES['myFile'])) {
// Example:
move_uploaded_file($_FILES['myFile']['tmp_name'], "uploads/" . $_FILES['myFile']['name']);
echo $_FILES['myFile']['name'];
exit;
}
?>
This works on Internet Explorer 11, Edge, Firefox, Chrome, Opera.
This example was derived from https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications
For a progress bar, see How to get progress from XMLHttpRequest

Related

AJAX in .PHP files

First question using the site so please bear with me if I haven't followed every rule in the book.
I come from a C++ background and don't have a great deal of experience with php/AJAX so I know that I probably have approached some of the following coding tasks in a sub-optimal/ improper way for writing code in different languages but anyway...
I have a Web site which uses a member login system written in PHP (connected to a mysql database), and the site is written using .php files to accomodate for this login system.
I want to use AJAX and JS on my .php pages to make them have a better user experience and I know this is possible (as I have done it), but I wanted to know if there are any negative/technical reasons why I shouldn't (and whether there are any better ways of doing this) as php is server side and AJAX is Client side.
Any advice would be appreciated.
Thanks
EDIT
I've added some code to show the type of things I would like to add to my php site
<?php
require "class.loginsys.php";
$LS = new LoginSystem();
$LS->init();
?>
<!-- HTML page structure -->
<!DOCTYPE html>
<html>
<head>
<title>OnyxProjectsPage</title>
<link rel="stylesheet" type="text/css" href="style.css" />
<script type = "text/javascript">
function createTable()
{
var xhr;
if (window.XMLHttpRequest) // Mozilla, Safari, ...
{
xhr = new XMLHttpRequest();
}
else if (window.ActiveXObject) // IE 8 and older
{
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
xhr.open("GET", "createDatabase.php");
//xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send();
xhr.onreadystatechange = display_data;
function display_data()
{
if (xhr.readyState == 4)
{
if (xhr.status == 200)
{
alert("Table Created");
}
else
{
alert('There was a problem with the request.');
}
}
}
}
</script>
</head>
<body>
<!-- Header background bar -->
<div id="container" style="width: 1920px">
<div id="header" style="background-color:#4c4c4c;">
<form class="well-home span6 form-horizontal" name="ajax-demo" id="ajax-demo">
<div class="controls">
<button type="button" onclick="createTable()">Create Testplan</button>
</div>
</form>
</body>
</html>
Using AJAX / JavaScript is not more dangerous than regular PHP. You can argue, that people can disable JavaScript and thus not be able to perform your expected result.
Usually, using AJAX will, as you mentioned, satisfy the user-experience, since they don't have to reload the page everytime a request is send.
The best solution, in my opinion, would be:
Check if the User enabled Javascript in his browser (keyword: noscript). If so, you can do use Frameworks like jQuery. Using this you can take advantage of the build-in ajax-function (take a look here). Otherwise prepare a fallback/failsafe mode for to serve every visitor.
LT;DR
Mix both of them. In any case, check and validate on serverside before inserting data in a database (or everything related to that kind of stuff), even if you checked it on the clientside already.
Personally, I prefer a combination of both, however not in same example as DasSaffe supplied.
I would write your PHP/HTML log-in page and when a user attempts to log in it runs your PHP script through an ajax request. If the PHP script returns success then ajax can redirect the user successfully.
The nice thing about this is that you can handle empty fields/invalid log-ins without ever leaving the page. If you use PHP only you will have to redirect the user to your script and then redirect back if there is an error.
Then you have to think, if I redirect my user back to the log-in page how do I tell the user that there was an error?

How to code this ActiveX function in PHP?

<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
function ShowFile(sFilePath){
var oFileSystem = new ActiveXObject("Scripting.FileSystemObject");
frmEditHTML.tarHTMLText.value = oFileSystem.OpenTextFile(sFilePath.value).ReadAll();
}
function SaveAfterEditing(sFilePath){
var oFileSystem = new ActiveXObject("Scripting.FileSystemObject");
var oFile = oFileSystem.CreateTextFile(frmEditHTML.filPath.value,1);
oFile.WriteLine(sFilePath.value);
oFile.Close();
}
</script>
</head>
<body>
<form name="frmEditHTML">
Select the File you want to Edit
<input type=file name="filPath" onchange="ShowFile(this)">
<textarea name="tarHTMLText" cols=60 rows=20></textarea>
<input type="button" value="Save" name="cmdSave" onclick="SaveAfterEditing(this.form['tarHTMLText'])">
</form>
</body>
</html>
I read this link and this link but they could not help!
I don't want to use ActiveX as then this function will be restricted to IE.
IE Tab in FireFox is also causes problems!
How can I replicate this whole function in PHP without using ActiveX ?
Please Help!
Short answer:
With PHP you can't convert this script exactly as it is, since ActiveX is client side and PHP is server side. Javascript can't do this for you either, since modern browsers are sandboxed, and JavaScript cannot access local file systems.
Not so short answer:
You have other options, however, depending on which behavior (and implementation method) you wish to mimic.
You can use a Java Applet that is able to do pretty much what you could do with ActiveX. Works consistently across browsers but user have to have installed Java Runtime Environment.
You can use a mix of PHP + Javascript (AJAX). You upload a file to the server and then control PHP actions with Javascript (HTTP Requests via Ajax).
Hackish way
There is an hackish simple way to handle this situation. Requires a server somewhere though.
Create a page that uploads a file to the server.
Then send the file back to the browser, via AJAX (or any request, doesn't matter).
Manipulate the file in the client side (browser) with javascript.
Give the file to the user to download.

FileSize through javascript

I want to check the file size of the file selected by user, at the client side by using javascript.The code i am using for this is:
<script type="text/javascript">
var myFile = document.getElementById('myfile');
//binds to onchange event of the input field
myFile.addEventListener('change', function() {
//this.files[0].size gets the size of your file.
alert(this.files[0].size);
});
</script>
But when i run the code, choose a file, nothing happpens.
Any body tell me what i am doing wrong
Your code works fine (in HTML5 browsers with the File API). Make sure that your <script> block is after the <input> element. In that jsfiddle, it's in the "load" handler.
Works for me using jquery:
http://jsfiddle.net/UUdcy/
$('#myfile').change( function() {
var fileInput = $("#myfile")[0];
var imgbytes = fileInput.files[0].fileSize; // Size returned in bytes.
$('body').append('<p>'+imgbytes+'</p>');
});​
You can't get the file size using javascript. Security in the browser prevents file system access by Javascript. You'd need to use Flash, or ActiveX or something that would be able to be granted permissions to do this I believe.
EDIT: If you are using the HTML5 File API then I guess you can do this - but as you've not indicated that anywhere I didn't assume that this was the case. I will put HTML as a tag on your post.

Is it possible to make an Ajax call and have PHP return headers?

I have a PHP script that produces a .CSV export file from a MySQL DB. The backend script formats the output and uses header()'s to open the pop-up window in the browser to download the .CSV. -- Tested and works fine.
I also have a web page that has a graphic button that launches an Ajax call to the server to produce the download .CSV file when you click the graphic button.
I tested the click event with a JavaScript alert() and it works fine.
I tested the click event with the Ajax call and nothing happens. Seems like I somehow need to direct the backend script to behave a bit differently.
Has anyone done anything similar to this before?
Thanks.
* HMTL (Excerpt) *
<div id="exportButton"><img src="images/export.png" alt="Export to Microsoft Excel Graphic" /></div>
<h2>Page Title</h2>
<br clear="all" />
<div id="pageContent_wrapper">...
* JavaScript *
<script>
jQuery.support.cors = true; // needed for ajax to work in certain older browsers and
versions
$(document).ready(function(){
$('#exportButton').click(function() {
//alert('button clicked');
$.ajax({
url: "http://mydomain.com/js/ajax/exportCSV.php"
});
});
}); // end .ready()
</script>
I am trying to accomplish this feature without having to send the user back to the server. I want the user to stay on the page.
You can't do a download from an AJAX call. The easiest solution is to wrap the button in an <a> element, and let the browser handle the download naturally. If you really need to have JS involved, change the document.location to point to the download PHP instead of invoking AJAX.
You can force the download of a file by setting the Content-type header to something that the browser will download by default, like an executable. Here's a quick example of a PHP script that does this:
header('Content-disposition: attachment; filename=huge_document.pdf');
header('Content-type: application/pdf');
readfile('huge_document.pdf');
Source: http://webdesign.about.com/od/php/ht/force_download.htm
Using this method you can link directly to the PHP script and avoid the JS calls. Note that forcing a Content-type of PDF will force a download in some browsers, and open the PDF Viewer Plugin in some browsers.

Replicate javascript to make requests/arguments to remote server using PHP

I am building an application that grabs html source from various sites.
Using xpath or simple html dom, I can then quite easily parse this html and dumb it to a database etc.
Unfortunately this approach does not work for one particular site.
This is because the site loads its content with JavaScript and so most of its content is not visible in the html source.
Having googled this over and over and read loads of threads covering the subject here on Stackoverflow. I'm still not sure how to go about solving this problem.
Here is the important part of the code this site is using to display its content.
<script type="text/javascript" src="/jquery-1.3.2.min.js"></script>
<script>
var example = {
getServiceCall:function(url) {
{
var srtPos=url.indexOf('Filter');
var endPos=url.indexOf('/',srtPos);
var filter = $.getUrlVar("Filter");
var filterInServiceUrl=url.slice(srtPos,endPos).split(":");
url = (filter)
? url.slice(0,srtPos) + filter + url.slice(endPos,url.length)
: url.slice(0,srtPos) + filterInServiceUrl[1] + url.slice(endPos,url.length);
}
document.writeln('<scri'+'pt src="'+url+'" type="text/javascript"> </sc' + 'ript>');
},
};
$.extend({
getUrlVars: function(){
var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
},
getUrlVar: function(name){
}
});
</script>
<div id="content">
<script language="javascript" type="text/javascript">
function doPerItem(html){ $("#content").html(html.toString()); }
example.getServiceCall('http://www.example.com/?callback=doPerItem');
</script>
</div>
Using Inspect Element in Google Chrome I can see that there is a file that contains html source that I want.
How can I use php to make the same request/arguments to the remote serve and then save the response to a file?
I will then be in a position to parse it with xpath or simple html dom just like the other sites.
Your help will much appreciated.
I don't know of any PHP-based remote access tool (including cURL) which interprets JavaScript. Selenium (normally used for testing) might do this, but Selenium-RC did not work for me at all with PHP and had bugs in the IDE.
You cannot practically use Ajax because that doesn't resolve JavaScript either (maybe you can resolve it somehow with eval() which has its security concerns), and JSONP will only work if the remote server is deliberately offering an API for getting its data (you could write your own proxy and then give the data as JSONP but then you'd still have the problem of resolving JavaScript).
What you could do (though it has real security risks for your site):
Write a file in PHP which simply gets the remote site's contents, using file_get_contents() and then outputs it (i.e., make a proxy).
Dynamically insert a hidden iframe via JavaScript to load your proxy page and then wait for the iframe's load event.
Get the resulting HTML of the hidden iframe from the parent and send back the result to the server.
You can't avoid step 1 unfortunately because you can't listen in on an iframe unless it comes from the same domain as yours.
Note that if the site you are visiting crafts their JavaScript in a certain way, they could access your containing HTML, and do things like grab your user's cookies so as to steal passwords, find out your domain or what's showing on your page, etc.
There may be better solutions out there, but I'm not aware of any.

Categories