source

레일 4: AJAX로 파일을 업로드하는 방법

ittop 2023. 10. 14. 10:37
반응형

레일 4: AJAX로 파일을 업로드하는 방법

AJAX와 함께 파일을 업로드하고 싶습니다.예전에 마법의 jQuery 플러그인을 사용하여 이를 달성하였는데, 잘 작동하였습니다.현재 저는 레일스 앱을 구축하고 "레일스 웨이" 작업을 시도하고 있기 때문에 Form Helper와 페이퍼 클립 보석을 사용하여 파일 첨부를 추가하고 있습니다.

레일 문서는 AJAX 파일 업로드에 대해 Form Helper가 작동하지 않는다고 경고합니다.

다른 양식과 달리 비동기 파일 업로드 양식을 만드는 것은 remote: true와 함께 form_for를 제공하는 것만큼 간단하지 않습니다.Ajax 형식의 경우 브라우저 내에서 실행되는 자바스크립트에 의해 직렬화가 이루어지며, 자바스크립트가 하드 드라이브에서 파일을 읽을 수 없으므로 파일을 업로드할 수 없습니다.가장 일반적인 해결 방법은 양식 제출의 대상이 되는 보이지 않는 iframe을 사용하는 것입니다.

기존의 해결책이 없는 것은 분명해 보입니다.그래서 저는 무엇이 가장 현명한 일인지 궁금합니다.몇 가지 옵션이 있는 것 같습니다.

  1. 폼 도우미와 iframe 트릭을 사용합니다.
  2. 폼 헬퍼 + load jQuery 폼 플러그인을 사용하여 파일을 제출합니다. (이것이 Rails의 인증 토큰 등과 잘 어울릴지 확실하지 않습니다.)
  3. 폼 헬퍼 + 페이퍼클립 + [다른 보석]을 사용하여 AJAX 폼 제출이 가능하도록 기능을 확장합니다.

셋 다 가능해 보입니다.3번, 특히 [다른 보석] 부분에 대해서는 가장 잘 모릅니다.나는 업로드파이라는 픽업로드의 한 분야를 언급하는 비슷한 질문(이것과 이것)을 두 개 발견했지만 둘 다 2년이 지났고 레일 2와 3을 다루고 있습니다(그리고 업로드파이는 몇 년 동안 업데이트되지 않았습니다).그래서 얼마나 많이 변했는지를 고려해 볼 때, 저는 이것이 정말 완전히 새로운 질문이라고 생각합니다.

레일 4에서 AJAX로 파일을 업로드하는 가장 좋은 방법은 무엇입니까?

에 대해 알아봅니다.remotipartgem: https://github.com/JangoSteve/remotipart -- 아주 적은 일로 여러분을 거기까지 데려다 줄 수 있을 것입니다.

@rails/ujs를 사용합니다.

보기(. html.erb):

<%= file_field_tag :file, { id: "ajax_file_upload"} %>

controller(_controller.rb):

def update
  @record = YourModel.find(params[:id])

  respond_to do |format|
    if @record.update_attributes(params[:your_model])
      format.json { render json: { success: true } }
    else
      error_messages = @record.errors.messages.values.flatten
      format.json { render json: { success: false, errors: error_messages } }
    end
  end
end

javascript (.js)

const uploadFile = element => {
  const formData = new FormData();
  formData.append("your_model[attribute_name]", element.target.files[0]);

  Rails.ajax({
    url: "your_model/:id",
    type: "PUT",
    beforeSend(xhr, options) {
      options.data = formData;
      return true;
    },
    success: response => {
      if (response.success) {
        alert("File uploaded successfully");
      }
      else {
        alert(response.errors.join("<br>"));
      }
    },
    error: () => {
      alert("ajax send error");
    }
  });
};

const documentOnReady = () => {
  const fileField = document.getElementById("ajax_file_upload");
  if (fileField) {
    fileField.addEventListener("change", uploadFile);
  }
}

document.addEventListener("turbolinks:load", documentOnReady);

참고: 요청을 설정할 필요가 없습니다.FormData를 사용하는 동안 ajax의 헤더.

FormData는 인코딩 유형이 "multipart/form-data"로 설정된 경우 폼에서 사용하는 형식과 동일한 형식을 사용합니다.

특히 프로그레스 바를 원하는 경우, AJAX를 사용하여 업로드 파일을 처리할 때 IMHO Rails는 완벽하지 않습니다.제 제안은 (2)에서 제안하신 것처럼 양식 제출을 위해 자바스크립트를 사용하는 것입니다.자바스크립트가 편하다면 큰 문제가 없을 것입니다.

저는 최근에 이 매우 간단한 JS 라이브러리 https://github.com/hayageek/jquery-upload-file 을 사용하여 동일한 접근 방식을 사용했으며 여기 http://www.alfredo.motta.name/upload-video-files-with-rails-paperclip-and-jquery-upload-file/ 에 더 많은 세부 정보를 썼습니다.

제목과 설명이 포함된 동영상을 업로드하는 양식을 가진 응용 프로그램의 경우 JS 코드는 다음과 같습니다.

$(document).ready(function() {
  var uploadObj = $("#movie_video").uploadFile({
    url: "/movies",
    multiple: false,
    fileName: "movie[video]",
    autoSubmit: false,
    formData: {
      "movie[title]": $('#movie_title').text(),
      "movie[description]": $('#movie_description').text()
    },
    onSuccess:function(files,data,xhr)
    {
      window.location.href = data.to;
    }
  });

  $("#fileUpload").click(function(e) {
    e.preventDefault();
    $.rails.disableFormElements($($.rails.formSubmitSelector));
    uploadObj.startUpload();
  });
});

완벽과는 거리가 멀지만 프론트엔드에서 유연성을 제공합니다.

언급URL : https://stackoverflow.com/questions/18595442/rails-4-how-to-upload-files-with-ajax

반응형