programing

Ajax 요청을 사용하여 파일 다운로드

copyandpastes 2022. 10. 30. 20:49
반응형

Ajax 요청을 사용하여 파일 다운로드

버튼을 클릭하면 "ajax download request"를 보내고 싶어서 다음과 같이 시도했습니다.

javascript:

var xhr = new XMLHttpRequest();
xhr.open("GET", "download.php");
xhr.send();

다운로드.php:

<?
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Disposition: attachment; filename= file.txt");
header("Content-Transfer-Encoding: binary");    
readfile("file.txt");
?>

기대했던 대로 되지 않습니다.어떻게 하면 좋을까요?잘 부탁드립니다.

2015년 4월 27일 갱신

HTML5 장면에 올라오는 것이 다운로드 속성입니다.Firefox와 Chrome에서 지원되며 IE11에도 곧 제공될 예정입니다.필요에 따라 AJAX 요청 대신 사용할 수 있습니다(또는window.location다운로드하는 파일이 사이트와 같은 원본에 있는 경우).

요청AJAX 요청은 든지 할 수 .window.location테스트에 JavaScript를 사용하여 폴백합니다.download되지 않는 을 'Call'로 하여 'Call"로 합니다.window.location.

원답

다운로드 프롬프트를 표시하려면 물리적으로 파일을 탐색해야 하므로 AJAX 요청에서 다운로드 프롬프트를 열 수 없습니다.대신 성공 함수를 사용하여 download.php로 이동할 수 있습니다.다운로드 프롬프트가 열리지만 현재 페이지는 변경되지 않습니다.

$.ajax({
    url: 'download.php',
    type: 'POST',
    success: function() {
        window.location = 'download.php';
    }
});

쓰는 게 요.window.location에이잭스

브라우저에서 파일을 다운로드하려면 다음과 같이 요청해야 합니다.

 function downloadFile(urlToSend) {
     var req = new XMLHttpRequest();
     req.open("GET", urlToSend, true);
     req.responseType = "blob";
     req.onload = function (event) {
         var blob = req.response;
         var fileName = req.getResponseHeader("fileName") //if you have the fileName header available
         var link=document.createElement('a');
         link.href=window.URL.createObjectURL(blob);
         link.download=fileName;
         link.click();
     };

     req.send();
 }

사실 에이잭스는 전혀 필요없어버튼의 href로 "download.php"를 설정했을 경우 또는 링크 사용이 아닌 경우:

window.location = 'download.php';

브라우저는 바이너리 다운로드를 인식하고 실제 페이지를 로드하지 않고 파일을 다운로드로 제공합니다.

크로스 브라우저 솔루션, Chrome, Firefox, Edge, IE11에서 테스트 완료.

DOM에서 숨김 링크태그를 추가합니다.

<a id="target" style="display: none"></a>

그 후, 다음과 같이 입력합니다.

var req = new XMLHttpRequest();
req.open("GET", downloadUrl, true);
req.responseType = "blob";
req.setRequestHeader('my-custom-header', 'custom-value'); // adding some headers (if needed)

req.onload = function (event) {
  var blob = req.response;
  var fileName = null;
  var contentType = req.getResponseHeader("content-type");

  // IE/EDGE seems not returning some response header
  if (req.getResponseHeader("content-disposition")) {
    var contentDisposition = req.getResponseHeader("content-disposition");
    fileName = contentDisposition.substring(contentDisposition.indexOf("=")+1);
  } else {
    fileName = "unnamed." + contentType.substring(contentType.indexOf("/")+1);
  }

  if (window.navigator.msSaveOrOpenBlob) {
    // Internet Explorer
    window.navigator.msSaveOrOpenBlob(new Blob([blob], {type: contentType}), fileName);
  } else {
    var el = document.getElementById("target");
    el.href = window.URL.createObjectURL(blob);
    el.download = fileName;
    el.click();
  }
};
req.send();

가능하다.예를 들어 .csv 파일이 생성된 직후에 ajax 함수 내부에서 다운로드를 시작할 수 있습니다.

연락처 데이터베이스를 .csv 파일로 내보내는 ajax 함수가 있습니다.이 함수가 완료되면 .csv 파일 다운로드가 자동으로 시작됩니다.responseText를 받고 모든 것이 OK가 되면 브라우저를 다음과 같이 리다이렉트합니다.

window.location="download.php?filename=export.csv";

다운로드.php 파일은 다음과 같습니다.

<?php

    $file = $_GET['filename'];

    header("Cache-Control: public");
    header("Content-Description: File Transfer");
    header("Content-Disposition: attachment; filename=".$file."");
    header("Content-Transfer-Encoding: binary");
    header("Content-Type: binary/octet-stream");
    readfile($file);

?>

페이지 리프레시는 일절 없고, 파일은 자동적으로 다운로드가 개시됩니다.

메모 - 다음 브라우저에서 테스트 완료:

Chrome v37.0.2062.120 
Firefox v32.0.1
Opera v12.17
Internet Explorer v11

는 는는더 prefer prefer ilocation.assign(url);

완전한 구문 예:

document.location.assign('https://www.urltodocument.com/document.pdf');

developer.mozilla.org/en-US/docs/Web/API/Location.assign

더 접근법으로는 '하다'를 할 수 있습니다.fetch API다음 예시는 스프레드시트 파일을 다운로드하는 방법을 보여 줍니다.이치하다

fetch(url, {
    body: JSON.stringify(data),
    method: 'POST',
    headers: {
        'Content-Type': 'application/json; charset=utf-8'
    },
})
.then(response => response.blob())
.then(response => {
    const blob = new Blob([response], {type: 'application/application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'});
    const downloadUrl = URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = downloadUrl;
    a.download = "file.xlsx";
    document.body.appendChild(a);
    a.click();
})

은 다른 보다 훨씬 합니다.XMLHttpRequest그리고은 이 문장.jQuery접라라 ( 라브브라라라라라라라 )

물론, IE에서는 새로운 어프로치가 동작하지 않기 때문에, 개발하시는 브라우저를 확인해 보시기 바랍니다.다음 링크에서 완전한 브라우저 호환성 목록을 찾을 수 있습니다.

중요:이 예에서는 JSON 요구를 수신하고 있는 서버에 송신하고 있습니다.url 이거.url세팅해야 합니다. 제 예에서는 이 부분을 알고 있다고 가정합니다.또한 요청에 필요한 헤더를 고려하십시오.에, JSON을 .Content-Type를 header로 합니다.application/json; charset=utf-8수신하는 요구의 타입을 서버에 통지합니다.

@Joao Marcos 솔루션은 나에게 효과가 있지만 IE에서 동작하도록 하기 위해 코드를 수정해야 했습니다.코드가 어떻게 보이는지는 다음과 같습니다.

       downloadFile(url,filename) {
        var that = this;
        const extension =  url.split('/').pop().split('?')[0].split('.').pop();

        var req = new XMLHttpRequest();
        req.open("GET", url, true);
        req.responseType = "blob";
        req.onload = function (event) {
            const fileName = `${filename}.${extension}`;
            const blob = req.response;

            if (window.navigator.msSaveBlob) { // IE
                window.navigator.msSaveOrOpenBlob(blob, fileName);
            } 
            const link = document.createElement('a');
            link.href = window.URL.createObjectURL(blob);                
            link.download = fileName;
            link.click();
            URL.revokeObjectURL(link.href);

        };

        req.send();
    },

헤더에서 파일 이름을 해독하는 것은 조금 더 복잡합니다.

    var filename = "default.pdf";
    var disposition = req.getResponseHeader('Content-Disposition');

    if (disposition && disposition.indexOf('attachment') !== -1) 
    {
       var filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
       var matches = filenameRegex.exec(disposition);

       if (matches != null && matches[1]) 
           filename = matches[1].replace(/['"]/g, '');
    }

이 솔루션은 위의 솔루션과 크게 다르지 않지만, 나에게는 매우 효과가 있고 깨끗하다고 생각합니다.

파일 서버측(PHP 를 사용하고 있는 경우는 base64_encode())을 부호화해, base64 로 부호화된 데이터를 클라이언트에 송신하는 것을 추천합니다.

클라이언트에서는, 다음의 조작을 실시합니다.

 let blob = this.dataURItoBlob(THE_MIME_TYPE + "," + response.file);
 let uri = URL.createObjectURL(blob);
 let link = document.createElement("a");
 link.download = THE_FILE_NAME,
 link.href = uri;
 document.body.appendChild(link);
 link.click();
 document.body.removeChild(link);

이 코드는 부호화된 데이터를 링크에 넣고 링크를 클릭하는 것을 시뮬레이트한 후 삭제합니다.

의 는 ★★★★★★★★★★★★★★★★★★★★★★★★window.location('download.php');
그러나 항상 같은 파일을 다운로드하는 것이 아니라 다운로드해야 할 파일을 전달해야 한다고 생각합니다."show file" "show file" "show file" "php" "show file" "show file" "show file" "show file" "show file" "show file" "show file" "show file" " file" "show" " file" "show" "hp" "hp" "hp" "hp" "hp" "hp" "hp" "hp" "" "show file" "h

var myfile = filetodownload.txt
var url = "shofile.php?file=" + myfile ;
ajaxRequest.open("GET", url, true);

show file을 클릭합니다.php

<?php
$file = $_GET["file"] 
echo $file;

여기서 file은 요청에서 Get 또는 Post를 통해 전달된 파일 이름이며, 그 후 단순히 함수로 응답을 캡처합니다.

if(ajaxRequest.readyState == 4){
                        var file = ajaxRequest.responseText;
                        window.location = 'downfile.php?file=' + file;  
                    }
                }

Ajax에서 웹 페이지를 다운로드하는 다른 솔루션이 있습니다.하지만 저는 먼저 처리하고 다운로드해야 하는 페이지를 말하는 것입니다.

먼저 페이지 처리와 결과 다운로드를 분리해야 합니다.

1) 페이지 계산만 ajax 콜에서 이루어집니다.

$.post("CalculusPage.php", {미적분: true, ID: 29, data1: "a", data2: "b"},
기능(데이터, 상태){if (상태 == "성공"){/* 2) 답변에서 이전 계산을 사용한 페이지가 다운로드됩니다.예를 들어, 이 페이지는 Ajax 콜에서 계산된 테이블의 결과를 출력하는 페이지입니다.*/window.location을 클릭합니다.href = DownloadPage.php+?ID="+29;}});
// 예: 미적분 페이지에 있습니다.php
!empty($_POST["calculus Function"])인 경우{$ID = $_POST["아이디];
$138 = "INSERT INTO ExamplePage (data1, data2) VALUES ('.$_POST["data1")"" , ' . $ _ POST [ " data 2 " ]") WHERE ID = ".$아이디...
}
// 예를 들어 Download Page에 있습니다.php
$ID = $_GET["아이디];
$sede = "SELECT * FROM ExamplePage WHERE ID = ".$"아이디...
$140="Export_Data.xls";header("Content-Type: application/vnd.ms-filename");
header("Content-Disposition: inline; filename=$disposition");

...

저도 그랬듯이 이 솔루션이 많은 사람에게 도움이 되었으면 합니다.

이거면 돼

var dataObj = {
somekey:"someValue"
}
     $.ajax({
        method: "POST",
        url: "/someController/someMethod",
        data: dataObj,
        success: function (response) {
            const blob = new Blob([response], { type: 'text/csv' });
            const downloadUrl = URL.createObjectURL(blob);
            const a = document.createElement("a");
            a.href = downloadUrl;
            a.download = "file.csv";
            document.body.appendChild(a);
            a.click();
        }
    });

언급URL : https://stackoverflow.com/questions/20830309/download-file-using-an-ajax-request

반응형