파일 업로드를 위한 아름다운 AJAX 형식입니다. HTML5: 드래그 앤 드롭을 사용하여 파일 업로드 드래그 앤 드롭으로 이미지 업로드




사용자가 예를 들어 데스크탑에서 파일을 끌어서 서버에 업로드할 수 있도록 허용합니다. 또한 여러 파일을 한 번에 끌어서 놓을 수도 있습니다.

해결책

위의 예에서 볼 수 있듯이 파일은 선택 직후 서버로 전송됩니다. 이벤트별로 보내자:

Window.onload = function())( var uploader = new qq.FileUploader(( autoUpload: false, element: document.getElementById("file-uploader"), action: "php/upload.php" )); $(" # startUpload").on("click", function())( uploader.uploadStoredFiles(); )); );

결과

일반적으로 플러그인에는 많은 옵션과 설정이 있으며 콜백도 있습니다. 이 모든 것이 설명되어 있습니다. Fineuploader는 지속적으로 개발 중이므로 링크 시 저장소를 방문하여 최신 버전을 다운로드 받는 것을 권장합니다.

양식화

플러그인은 .qq-uploader 클래스를 기반으로 구조를 생성하며 모든 요소는 CSS 파일 fileuploader.css에 설명되어 있습니다.

메모에

당나귀가 고집스럽게 작업을 거부하는 경우 스크립트를 열고 거기에서 다음 줄을 찾으십시오.

변형 형식 = qq.toElement("");

다음으로 변경합니다.

변형 형식 = qq.toElement("");

물론 먼저 파일을 "잡을" 요소를 만들어야 합니다. 또한 이 요소에 스팬 태그를 배치하여 로딩 상태에 대한 메시지를 표시하고 입력유형으로 파일, 드래그 앤 드롭으로 파일 선택을 제한하지 않고 사용자가 지정된 영역을 클릭하여 파일을 선택할 수 있도록 합니다. 이러한 구조의 최종 형태는 아래와 같습니다.

여기를 클릭하거나 업로드할 파일을 끌어다 놓습니다.

CSS이에 HTML현장 디자인을 제외하면 코드는 눈에 띄지 않습니다. 입력:

#file(너비:100%; 높이:100%; 표시:블록; 위치:절대; 위쪽:0; 왼쪽:0; 불투명도:0.01; )

또한 파일의 "캡처" 영역에 추가되면 성공적인 파일 다운로드를 알리거나 오류가 발생할 경우 오류를 알리는 두 가지 클래스에 대해서도 설명합니다.

#drop-zone.success( 배경색:#2ecc71; ) #drop-zone.error( 배경색:#e74c3c; )

이제 페이지의 "액션" 작성으로 넘어갈 수 있습니다. 먼저, 자주 액세스할 객체에 대한 참조를 변수에 작성해 보겠습니다.

Var dropZone = document.getElementById("drop-zone"); var msgContainer = document.querySelector("#drop-zone .text");

그런 다음 커서가 파일 수신 영역에 닿을 때 다음과 같이 기본 이벤트를 제거합니다.

Var eventClear = function (e) ( e.stopPropagation(); e.preventDefault(); ) dropZone.addEventListener("dragenter", eventClear, false); dropZone.addEventListener("dragover", eventClear, false);

DropZone.addEventListener("drop", function (e) ( if(!e.dataTransfer.files) return; e.stopPropagation(); e.preventDefault(); sendFile(e.dataTransfer.files); ), false); document.getElementById("file").addEventListener("change", function (e) ( sendFile(e.target.files); ), false);

두 경우 모두 이벤트는 함수 호출로 끝납니다. 파일 보내기, 사용자로부터받은 파일이 전송됩니다.

이 기능은 파일을 서버로 전송하는 역할을 합니다. 아래에서 해당 설명을 볼 수 있습니다.

Var sendFile = function(file) ( // 추가되었을 수 있는 상태 클래스 제거 // 사용자가 이미 다운로드를 시도한 경우 dropZone.classList.remove("success"); dropZone.classList.remove("error") ; // 파일 형식에 대한 정규식을 사용하여 확인 // (예제에서는 이미지만 로드가 허용됨) var re = /(.jpg|.jpeg|.bmp|.gif|.png)$/i ; exec(file.name)) ( msgConteiner.innerHTML = "잘못된 파일 형식!"; dropZone.classList.remove("성공"); dropZone.classList.add("error"); ) else ( var fd = new FormData ( ); // 양식 객체 생성 fd.append("upfile", file); // 제출 양식에 파일 추가 var xhr = new XMLHttpRequest() ); = statChange; // 서버로 전송 )

아시다시피 서버에 데이터를 보내기 전에 두 가지 이벤트도 설정됩니다. 첫 번째는 다운로드 진행률을 표시하고 두 번째는 다운로드 결과를 알리는 역할을 합니다. 그들은 다음과 같이 작동합니다:

Var showProgress = function(e) ( if (e.lengthComputable) ( // 로딩 비율을 계산합니다. var Percent = Math.floor((e.loaded / e.total) * 100); // 현재 비율을 표시합니다 msgConteiner.innerHTML = " 로드 중... ("+ 퍼센트 +"%)" ) ); var statChange = function (e) ( if (e.target.readyState == 4) ( // 서버에 대한 요청 처리가 완료되면 if (e.target.status == 200) ( // 요청이 성공한 경우 msgConteiner.innerHTML = "업로드가 성공적으로 완료되었습니다!"; dropZone.classList.add("success"); document.getElementById("showUpFile").innerHTML = this.responseText) // else msgConteiner.innerHTML = "오류가 발생했습니다!"; dropZone.classList.remove("success"); dropZone.classList.add("error" ) )

마지막 단계는 서버에서 수신한 데이터를 처리하는 것입니다.

이 마크업은 드래그 앤 드롭과 특별히 관련이 없습니다. 비록 잠재적인 상태에 대한 추가 HTML 요소가 있기는 하지만 이는 단지 정상적이고 기능적인 것입니다.

파일을 선택하거나 여기로 드래그하세요. 업로드 완료! 오류! .

필요할 때까지 해당 상태를 숨길 것입니다.

Box__dragndrop, .box__uploading, .box__success, .box__error (표시: 없음; )

약간의 설명:

  • 상태 관련: .box__uploading 요소는 파일 업로드의 Ajax 프로세스 중에 표시됩니다(다른 요소는 여전히 숨겨집니다). 그러면 무슨 일이 일어나는지에 따라 .box__success 또는 .box__error가 표시됩니다.
  • 입력과 레이블은 양식의 기능적 부분입니다. 파일 입력 사용자 정의에 대한 내 게시물에서 이러한 스타일을 함께 스타일링하는 방법에 대해 썼습니다. 그 게시물에서 나는 속성의 목적에 대해서도 설명했습니다. 입력 및 레이블은 표준 방식(또는 드래그 앤 드롭이 지원되지 않는 경우 유일한 방법)으로 파일을 선택하기 위한 대안으로도 사용됩니다.
  • .box__dragndrop은 브라우저가 드래그 앤 드롭 파일 업로드 기능을 지원하는 경우 표시됩니다.
특징 감지

드래그 앤 드롭을 지원하는 브라우저에 100% 의존할 수는 없습니다. 대체 솔루션을 제공해야 합니다. 따라서 다음과 같습니다. 특징 감지. 드래그 앤 드롭 파일 업로드는 다양한 JavaScript API에 의존하므로 이를 모두 확인해야 합니다.

어떤 경우에는 서비스 개발자가 책임을 져야 할 수도 있지만, 문제는 브라우저가 부과하는 제한 사항에 있는 경우가 많습니다. 서버에 파일을 업로드하는 것을 고려해 보겠습니다.

대부분의 경우 컴퓨터에서 파일을 선택할 수 있는 버튼이 있는 표준 필드 및/또는 인터넷 어딘가에 있는 파일의 URL을 지정할 수 있는 필드가 표시됩니다.

지금은 로컬 컴퓨터에서 파일을 다운로드하는 방법을 다루지 않을 것입니다. 이 주제에 대해 별도의 게시물을 게시할 계획입니다. 원격 서버에서 다운로드하는 방법을 살펴보겠습니다.

문제는 첫 번째 단계부터 시작됩니다. URL을 찾을 위치를 명확하게 이해하고 Firebug와 같은 도구를 능숙하게 사용하더라도 올바른 주소를 얻으려면 몇 번의 클릭이 필요합니다. 한 브라우저 창에서 다른 브라우저 창으로 원하는 이미지를 드래그하는 것이 훨씬 더 편리할 것입니다.

이 기사에서는 그러한 인터페이스의 구현을 보여 드리겠습니다. 원한다면 데모 페이지에서 작동 방식을 확인하거나 소스가 포함된 아카이브를 다운로드할 수 있습니다.

메모! 이 예제는 Google Chrome 브라우저에서만 작동합니다. 이론적으로는 Firefox와 Safari에서 필요한 모든 기술에 대한 지원이 가능하지만 아직 파악하지 못했습니다.

'끌기'의 대상으로는 위키피디아에서 주로 사진을 찍었습니다. 이미지의 URL에서 라틴어가 아닌 문자와 관련된 몇 가지 문제가 발견되었지만 확인 및 변환으로 예제에 과부하가 걸리지 않도록 그대로 두었습니다.


작동 원리

HTML5 표준은 페이지 개체 드래그 앤 드롭을 지원합니다. 그건 그렇고, 나는 이미 HTML5를 사용한 드래그 앤 드롭이라는 가장 간단한 D&D 구현의 예를 보여주었습니다. 게다가 D&D 지원을 구현하는 JavaScript 라이브러리도 꽤 많이 있습니다.

그러나 여기서는 타사 리소스에서 사진을 "드래그"해야 하는 경우 라이브러리를 사용할 수 없다는 점을 이해하는 것이 중요합니다. 왜냐하면 다른 사람의 페이지에 JS 코드를 추가할 수 없습니다. 그리고 사진을 다운로드하려면 해당 URL을 가져와야 합니다. 또한 브라우저는 드래그된 객체와 함께 해당 매개변수를 전송해야 합니다(예: 이미지의 src 속성 또는 전체 img 태그).

이 경우 페이지에 사진의 "수신자"를 만들 수 있습니다. 이는 드롭 이벤트 핸들러가 할당된 일반 div입니다. 사용자가 이 div 위에 이미지를 "드롭"하면 핸들러가 호출되고 첫 번째 매개변수에서 드래그되는 이미지에 대한 정보가 포함된 객체를 수신합니다.

구현

신청 페이지부터 시작해 보겠습니다.





이미지 업로드








여기에는 두 개의 블록이 포함되어 있습니다. 이미지 - 여기에는 로드된 이미지가 표시되며 img_target은 이 블록에 그림을 끌어야 합니다.

페이지 하단에서 드래그한 이미지에 대한 정보를 서버로 보내는 jQuery 라이브러리와 main.js 스크립트를 연결합니다.

main.js를 살펴보겠습니다.

$(함수() (
$("#img_target")
.bind("dragenter", function(event) (
$(this).addClass("drop_here");
거짓을 반환;
})
.bind("dragleave", function(event) (
거짓을 반환;
})
.bind("드래그오버", function(event) (
거짓을 반환;
})
.bind("drop", function(event) (
$(this).removeClass("drop_here");
var srcRegex = /src=\"([^\s]+)\"/ig;
var data = event.originalEvent.dataTransfer.getData("text/html");
var img_data = srcRegex.exec(data);
$.post("upload.php", ("file_url":img_data), 함수(res) (
var response = eval("(" + res + ")");
$("#이미지").append($(" "));
});
사실을 반환;
});

여기서는 dragenter, dragleave 및 dragover 이벤트에 핸들러를 할당합니다. 이들 모두는 단순히 false를 반환해야 하며 사용자에게 이미지가 "드롭"될 수 있음을 알리기 위해 dragenter 핸들러에서 수신자 블록에 대해 CSS 클래스 drop_here를 설정합니다.

대부분의 작업은 drop 이벤트 핸들러에서 수행됩니다. 이 이벤트가 발생하면 "reset" 개체에 대한 정보를 읽고 src 속성의 값을 "삭제"합니다. 이미지의 URL(16-18행) 정보는 event.originalEvent.dataTransfer 객체(17행)에서 전송됩니다.

그런 다음 일반 AJAX 요청을 구성하고 찾은 URL을 매개변수로 전달합니다.

서버 스크립트(upload.php)는 원격 서버에 있는 이미지의 URL을 받아 업로드합니다. 그리고 AJAX 요청에 대한 응답으로 로드된 이미지의 새 URL을 보냅니다.

그러면 AJAX 요청 핸들러는 img 태그를 생성하고 이를 이미지 블록에 삽입합니다. 따라서 다운로드한 사진은 다운로드 필드 위에 표시됩니다.

upload.php를 고려해보세요.

정의("BASE_URL", "http://localhost/tests/images-upload/");

함수 upload_from_url($file_url) (
$url_segments = 폭발("/", $file_url);
$file_name = urldecode(end($url_segments));
if (false !== $file_name) (
$file_name_parts = 폭발(".", $file_name);
if (in_array(strtolower(end($file_name_parts)), array("jpeg","jpg","png","gif"))) (
$destination=fopen("업로드/".$file_name,"w");
$source=fopen($file_url,"r");
$최대크기=300*1024;
$길이=0;
while (($a=fread($source,1024))&&($length "파일 URL이 지정되지 않았습니다.");

if (isset($_POST["file_url"])) (
$new_url = upload_from_url($_POST["file_url"]);
$res = array("file_url" => $new_url);
}

echo json_encode($res);

작동 원리는 다음과 같습니다. 이미지의 URL을 읽고 다운로드를 시도합니다(29-32행).

이미지가 업로드되면 업로드 폴더에 저장하세요. 원격 서버로부터 이미지 수신은 fread 함수를 사용하여 수행됩니다. 파일은 1kB 블록 단위로 읽혀집니다(라인 15-18). 이 접근 방식을 사용하면 파일 크기가 지정된 제한(이 경우 300kB)을 초과하는 경우 파일 다운로드를 중단할 수 있습니다.

파일을 다운로드한 후 해당 URL을 생성하여 JSON 형식으로 브라우저에 보냅니다.

보시다시피, 이러한 부트로더를 구현하는 것은 어렵지 않습니다. 그리고 사용하기가 꽤 편리합니다. 당연히 가장 큰 단점은 HTML5에 대한 브라우저 지원 또는 오히려 HTML5가 부족하다는 것입니다.

그러나 회사 직원을 위한 인터페이스를 만들고 브라우저 유형을 지정할 수 있는 경우 HTML5를 사용할 수 있습니다.

이번 강의에서는 멋진 Dropzone.js 플러그인을 PHP 웹 사이트와 통합하여 단 몇 줄의 코드만으로 서버에 파일을 업로드하는 예를 보여 드리겠습니다.

Dropzone.JS는 파일 미리보기와 함께 파일 업로드를 위한 드래그 앤 드롭 인터페이스를 제공하는 바닐라 JS로 작성된 훌륭한 오픈 소스 라이브러리입니다.

먼저 최신 버전의 라이브러리와 해당 스타일을 다운로드합니다.

그런 다음 업로드 폴더와 파일 index.php 및 upload.php를 만듭니다.

인덱스 PHP 파일은 사이트에 자료를 추가하기 위한 양식이 포함된 코드의 일부일 수 있습니다. 내 예에서는 최소한의 마크업과 포함된 Dropzone.js 라이브러리 및 스타일을 사용하여 빈 페이지를 만듭니다.

아마도 눈치채셨겠지만, 우리는 upload.php 액션을 사용하여 양식을 생성했지만 파일 첨부를 위한 입력을 생성하지 않았으며 양식의 enctype을 선언하지 않았습니다. 여기에는 오류가 없으며 모든 것이 DropzoneJS 라이브러리 자체에서 처리됩니다. 우리가 해야 할 일은 양식에 dropzone 클래스를 제공하는 것뿐입니다. 기본적으로 DropzoneJS는 이 클래스가 포함된 모든 양식을 찾아 자동으로 해당 인터페이스를 그립니다.

브라우저에서 실행할 index.php 페이지를 열고 라이브러리가 의도한 대로 작동하는지 확인할 수 있습니다. 내가 얻은 것은 다음과 같습니다.

이제 이미 upload.php 파일을 생성한 업로드 핸들러를 생성해 보겠습니다. 다음은 가장 간단한 로딩 코드의 예입니다.

다운로드한 파일 작업

파일과 완벽하게 상호 작용하려면 해당 파일을 조작하는 기능만 추가하면 됩니다. 먼저 저장된 파일에 대한 정보(이름 및 크기)를 추출하고 이를 JSON 형식으로 반환하는 코드 조각을 추가해야 합니다.

이렇게 하려면 upload.php 파일을 다음 형식으로 업데이트하세요(else 조건이 삽입됨).

  • PHP scandir 함수는 업로드 폴더를 스캔하고 파일 배열을 반환하거나 폴더가 비어 있으면 FALSE를 반환합니다.
  • scandir 함수의 반환 값을 반복하여 $result 배열에 저장합니다. 기억하세요. 우리는 "."을 무시합니다. 그리고 ".."는 scandir이 항상 "."을 반환하기 때문입니다. 그리고 ".."는 현재 및 이전 디렉터리와 관련된 유효한 콘텐츠입니다.
  • JSON 마크업에 대한 올바른 헤더를 출력하고 json_encode 함수를 사용하여 PHP 배열을 JSON 문자열로 변환합니다.
  • 이제 index.php를 업데이트할 시간입니다:

    Dropzone.options.myDropzone = ( init: function() ( thisDropzone = this; $.get("upload.php", function(data) ( $.each(data, function(key,value)( var mockFile = ( 이름 : value.name, size: value.size ); thisDropzone.options.addfile.call(thisDropzone, mockFile); thisDropzone.options.thumbnail.call(thisDropzone, mockFile, "uploads/"+value.name ))) ;

    우리는 여기서 무엇을 했나요? 그것을 알아 봅시다 :

  • 아쉽게도 Jquery 라이브러리를 페이지에 추가했습니다. 이는 실제로 DropzoneJ에 필요한 것은 아닙니다. 우리는 JQuery $.get ajax 함수만 사용하고 있습니다. 귀하의 재량에 따라 vue.js 또는 원하는 대로 유사한 요청을 구현할 수 있습니다.
  • 양식에 ID 요소(my-dropzone)를 추가했습니다. 이는 구성 값을 Dropzone으로 전송하기 위해 필요합니다. 이를 위해서는 이를 가리키는 고유 식별자가 있어야 합니다. 이렇게 하면 Dropzone.options.myDropzone에 값을 할당하여 라이브러리를 구성할 수 있습니다.
  • 편집의 주요 부분을 초기화해 보겠습니다. 여기서 수행한 작업은 Dropzone에 대한 init 이벤트를 수신하는 함수를 전달했습니다. 이 이벤트는 Dropzone이 초기화되면 시작됩니다.
  • ajax를 사용하여 “upload.php”로부터 파일 배열을 받습니다.
  • 서버의 값을 사용하여 mockFile을 만듭니다. MockFiles는 이름과 크기 속성을 가진 단순한 JavaScript 객체입니다. 그런 다음 명시적으로 Dropbox 함수를 호출하고 아이콘을 추가하여 기존 파일을 Dropzone 업로드 영역으로 가져오고 해당 파일의 썸네일을 만듭니다.
  • 모든 일을 올바르게했다면. 일부 이미지를 업로드하고 양식 페이지를 다시 로드하세요. 이전에 업로드한 파일은 Dropzone 영역에 자동으로 나타납니다.