javascript - 해결 - 크롬 파일 업로드 fakepath



페이지에 파일을 놓을 때 파일 입력 값을 설정하는 방법은 무엇입니까? (1)

나는 폼에서 제출할 파일을 선택하고 같은 것을하기 위해 파일을 드롭 할 수있는 컨트롤을 시도하고있다. 이미지의 경우 파일의 미리보기가 표시되는 위치는 다음과 같습니다.

<div class="preview-image-container">

  <input type="file" name="File" id="File" accept="image/*" 
         class="image-url form-control" style="display:none;" />

  <div class="preview-image-dummy"></div><img class="preview-image-url" />
  <div class="preview-image-instruction">
    <div class="preview-image-btn-browse btn btn-primary">Select file</div>
    <p>or drop it here.</p>
  </div>

</div>

여기에 MCVE가있는 바이올린이 있습니다 .

사용자가 파일을 preview-image-container . 파일이 AJAX와 함께 제출되지 않았 으면 사용자는 더 많은 데이터를 포함하는 양식을 제출해야합니다.

보안상의 이유로 JavaScript로 입력 파일의 값을 변경할 수 없습니다. 그러나 기본 입력 파일 지원이 삭제 가능하다는 것을 알고 있으며 양식을 삭제하여 파일을 선택할 수 있도록하는 웹 사이트가 있으므로 내 방식은이를 수행 할 방법이 있다는 것입니다.

MCVE에서 볼 수 있듯이 jQuery 나 순수한 JavaScript 를 추가 라이브러리없이 사용하는 것에 만 관심이 있습니다.

dropzone.js를 사용할 수도 있지만 내 요구 사항에 맞지 않으므로 모양을 사용자 정의하는 데 많은 시간이 필요합니다. 또한 dropzone.js 에는 ASP.NET 응용 프로그램 내에서 충족시킬 수없는 특정 구성 요구 사항이 있습니다.

비슷한 질문이 있지만 적절한 답변이 없습니다.
파일 객체를 HTML 형식의 입력 파일로 설정하는 방법은 무엇입니까?

또한 끌어 놓기 및 미리보기 작업을 이미 수행했기 때문에 끌어서 놓기 이미지 입력 ​​파일 및 업로드 전에 미리보기 와 유사하지 않습니다. 내 질문은 부모 컨테이너에서 파일을 삭제할 때 빈 파일 입력 문제에 관한 것입니다.


면책 조항 : 2017 년 12 월 및 최신 브라우저에서만 수정하십시오.

TL : 예, 할 수 있습니다!

* dataTransfer 또는 FileList 객체가있는 경우

이전 에는 파일 input[type=file] 필드를 프로그래밍 방식으로 변경하는 것이 최신 브라우저에서 수정 된 기존 보안 취약점으로 인해 비활성화되었습니다.

마지막으로 주요 브라우저 (Firefox)에서 입력 파일 필드의 파일을 설정할 수있었습니다. W3C 테스트 에 따르면, 이미 Chrome에서이 작업을 수행 할 수 있습니다!

MDN에서 인용 한 관련 스크린 샷과 텍스트 :

현대의 모든 브라우저에서 HTMLInputElement.files 의 값을 설정 하고 설정할 수 있습니다.
소스 및 브라우저 호환성, 참조

파이어 폭스 버그 픽스 토론 스레드는 그것을 시험해 수있는 데모를 가지고 있습니다 . 편집하고 싶다면 여기에 소스가 있습니다 . 이 링크가 죽어 버리면 나중에 참조 할 수 있도록 아래의 실행 가능한 스 니펫으로 포함시킵니다.

let target = document.documentElement;
let body = document.body;
let fileInput = document.querySelector('input');

target.addEventListener('dragover', (e) => {
  e.preventDefault();
  body.classList.add('dragging');
});

target.addEventListener('dragleave', () => {
  body.classList.remove('dragging');
});

target.addEventListener('drop', (e) => {
  e.preventDefault();
  body.classList.remove('dragging');
  
  fileInput.files = e.dataTransfer.files;
});
body {
  font-family: Roboto, sans-serif;
}

body.dragging::before {
  content: "Drop the file(s) anywhere on this page";
  position: fixed;
  left: 0; width: 100%;
  top: 0; height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 1.5em;
  background-color: rgba(255, 255, 0, .3);
  pointer-events: none;
}

button, input {
  font-family: inherit;
}

a {
  color: blue;
}
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
      <link href="https://fonts.googleapis.com/css?family=Roboto:400,400i,700" rel="stylesheet"> 

  <title>JS Bin</title>
</head>
<body>
  
  <h1>Drag and drop files into file input</h1>
  
  <p><small>Supported in <a href="https://github.com/whatwg/html/issues/2861">WebKit and Blink</a>. To test, drag and drop one or more files from your operating system onto this page.</small></p>
  
  <p>
    <input type="file">
  </p>

</body>
</html>

중요 사항:

setter 메서드가 일반 텍스트 문자열을 허용하지 않으므로 입력 파일 요소로 설정할 수있는 기존 FileList 또는 dataTransfer 개체가있는 경우에만이 작업을 수행 할 수 있습니다.

자세한 내용은 Kaiido의 대답을 참조하십시오 : FileList 객체에서 File 객체 및 length 속성을 설정하는 방법 파일이 FormData 객체에도 반영되는 방법은 무엇입니까?

이제 원래의 질문에 답하기 위해 다음과 같이 간단해야합니다.

document.querySelector('.preview-image-instruction')
    .addEventListener('drop', (ev) => {
        ev.preventDefault();
        document.querySelector('.image-url').files = ev.dataTransfer.files;
    });




events