01/10/2018, 16:54

Upload ảnh bằng ajax và PHP

Trong bài viết này mình sẽ sử dụng lại những kiến thức cơ bản mà mình đã trình bày ở các bài viết trước. Nếu bạn chưa hoặc đã tìm hiểu nhưng bạn chưa thực sự lắm rõ thì bạn có thể tìm hiểu một số kiến thức cơ bản sau. Kiến thức về upload file trong PHP Kiến thức về JQuery ajax 1. ...

Trong bài viết này mình sẽ sử dụng lại những kiến thức cơ bản mà mình đã trình bày ở các bài viết trước. Nếu bạn chưa hoặc đã tìm hiểu nhưng bạn chưa thực sự lắm rõ thì bạn có thể tìm hiểu một số kiến thức cơ bản sau.

  • Kiến thức về upload file trong PHP
  • Kiến thức về JQuery ajax

1. JavaScript

Đầu tiên bạn cần nhúng vào thư viện của JQuery.

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>

2. HTML Form

Bạn cần xây dựng một form HTML đơn giản. Bạn cần lưu ý rằng thuộc tính enctype="multipart/form-data"

<div class="media-form">
    <form id="frmIssue" method="post" action="" enctype="multipart/form-data">
        <div class="media-preview">
            <img id="image-preview" awidth="100%" height="100%" />
        </div>
        <hr />
        <div class="message success"></div>
        <div class="loading"></div>
        <div class="media-upload">
            <div class="form-group">
                 <label>Lựa chọn hình ảnh</label>
                 <input class="form-control" type="file" name="file" id="file" />
            </div>
            <div class="form-group">
                <input type="hidden" name="action" value="upload" />
                <input class="btn btn-default" type="submit" id="submit" value="Upload" />
            </div>
        </div>
    </form>
</div>

3. Script JQuery + Ajax

Để có thể xem trước hình ảnh sau khi hình ảnh đó được tải nên server-side thì có thể có rất nhiều cách. Nhưng bản thân mình thì mới chỉ biết có hai cách thôi. Thì chúng ta sẽ bắt sự kiện change của phần tử HTML input file có ID là file

Cách 1: Sử dụng đối tượng FileReader

if ( window.FileReader ) {
	var reader = new FileReader();
	reader.onload = function (e) {
		$('#image-preview').attr('src', e.target.result);
	}
	reader.readAsDataURL(this.files[0]);
}

Cách 2: Sử dụng phương thức createObjectURL

var $_t = window.URL || window.webkitURL;	
var $_objectURL = $_t.createObjectURL($_files);
$('#image-preview').attr('src', $_objectURL);

Nói chung trong hai cách này bạn chọn cách nào cũng được. Nhưng có một điều bạn cần lưu ý rằng chức năng xem trước này chỉ chạy được trên các trình duyệt hiện đại hoặc IE 10 trở nên.

3 . Code hoàn chỉnh.

$(document).ready(function(){
	$('#frmIssue').on('submit', function(e){
		e.preventDefault();
		//sử dụng ajax post
		$.ajax({
        	url: "upload_file.php",   	
			type: "POST",
			beforeSend: function(xhr){
				$('.loading').show();
			},
			processData: false,
			contentType: false,  				
			data: new FormData(this),
			success: function(html){
				$('.loading').hide();
				if(html.indexOf('_invalid_type') >= 0){
					alert('Kiểu file không được phép !');
				} else if(html.indexOf('_invalid_size') >= 0){
					alert('Kích thước file không được vượt quá 2MB !');
				}else{
					// upload thành công
					$("#frmIssue").trigger('reset');
					$('#image-preview').attr('src', html);
					$('.message').text('Upload thành công !').fadeIn().delay(2000).fadeOut();
				}
			}
	   });
	});
	$('#file').change(function(){
		if (this.files && this.files[0]) {
			//Lấy ra files
			var $_files = this.files[0];
			//lấy ra kiểu file
			var $_ext = $(this).val().substring($(this).val().lastIndexOf('.') + 1).toLowerCase();
			//Xét kiểu file được upload
			var $_validFileExtensions= ["jpeg","png","jpg",'gif'];
			//kiểm tra kiểu file
			if($.inArray($_ext, $_validFileExtensions)==-1){
				alert('Invalid file type (jpg,png,gif) !');
			}else{
				var $_t = window.URL || window.webkitURL;	
				var $_objectURL = $_t.createObjectURL($_files);
				$('#image-preview').attr('src', $_objectURL);
				/*if ( window.FileReader ) {
					var reader = new FileReader();
					reader.onload = function (e) {
						$('#image-preview').attr('src', e.target.result);
					}
					reader.readAsDataURL(this.files[0]);
				}*/
			}
		}
	});
});

Thông thường khi thực hiện chức năng này mình thường sử dụng JQuery form plugin. Nó cho phép bạn gửu tất cả dữ liệu form nên server mà không reload lại trang.

<script src="http://malsup.github.com/jquery.form.js"></script>

Trong bài viết này mình không sử dụng JQuery form plugin nữa mà thay vào đó mình sẽ sử dụng bắt sự kiện submit của form. và sử dụng đối tượng FormData() của javascript.

Lưu ý: Khi sử dụng đối tượng này bạn phải thiết lập hai thuộc tính dưới đây.

  • processData: false,
  • contentType: false, 

Nếu bạn không thiết lập hai thuộc tính này thì hệ thống sẽ báo lỗi script.

Nếu bạn muốn sử dụng JQuery form plugin thì bạn có thể thay đoạn code đầu bằng đoạn code sau đây. Nhưng bạn cần thay đổi một chút thay vì mình bắt sự kiện submit của form thì giờ đây ta cần bắt sự kiền click của button và bạn nên chuyển type="sybmit" của button Upload thành type="button".

4. Sử dụng JQuery form

$('#submit').click(function(e){
	e.preventDefault();
	//sử dụng ajax post
	$('#frmIssue').ajaxSubmit({
		type: "POST",
		url: "upload_file.php", 
		beforeSend: function(xhr){
			$('.loading').show();
		},
		success: function(html){
			$('.loading').hide();
			if(html.indexOf('_invalid_type') >= 0){
				alert('Kiểu file không được phép !');
			} else if(html.indexOf('_invalid_size') >= 0){
				alert('Kích thước file không được vượt quá 2MB !');
			}else{
				// upload thành công
				$("#frmIssue").trigger('reset');
				$('#image-preview').attr('src', html);
				$('.message').text('Upload thành công !').fadeIn().delay(2000).fadeOut();
			}
		}
	});
});

4. Xử lý upload file.

if(isset($_POST['action']) && $_POST['action']=='upload'){
    $upload_url = '/demo/upload-image-ajax-php/uploads/';
    $upload_path = dirname(__FILE__).'/uploads/';
    // Check file type
    $validextensions = array("image/jpeg", "image/jpg", "image/png", "image/gif");
    if(!in_array($_FILES['file']['type'],$validextensions)){
        echo '_invalid_type';
        die();	
    }
    // Check file size
    if($_FILES['file']['size'] > 2000000){
        echo '_invalid_size';
        die();	
    }
    
    $name = $upload_url.$_FILES['file']['name'];
    $dest = $upload_path.$_FILES['file']['name'];
    if(is_uploaded_file($_FILES['file']['tmp_name'])){
        @move_uploaded_file($_FILES['file']['tmp_name'], $dest);
    }
    echo $name; die();
}

5. Tổng kết.

Như vậy mình đã trình bày với các bạn chức năng upload ảnh thông qua ajax+PHP kèm theo tính năng xem ảnh đó trước khi được tải nên phía server-side.

0