Javascript를 사용하여 오프라인 양식 만들기 🤩

13063 단어
**웹의 양식은 일반적으로 연결 상태가 좋지 않으면 잘 작동하지 않습니다. **오프라인 상태에서 양식을 제출하려고 하면 입력 내용이 손실될 가능성이 큽니다. 문제를 해결하는 방법은 다음과 같습니다.

이 게시물의 CodePen Demo입니다.

서비스 작업자의 도입으로 개발자는 이제 인터넷 연결 없이도 작동하는 웹 환경을 제공할 수 있습니다. 정적 리소스를 캐시하는 것은 상대적으로 쉽지만 서버 상호 작용이 필요한 양식과 같은 항목은 최적화하기가 더 어렵습니다. 그래도 다소 유용한 오프라인 폴백을 제공하는 것은 가능합니다.

먼저 오프라인 친화적 양식을 위한 새 클래스를 설정해야 합니다. <form> 요소의 몇 가지 속성을 저장한 다음 제출 시 실행되는 *함수 *를 첨부합니다.

class OfflineForm {
  // setup the instance.
  constructor(form) {
    this.id = form.id;
    this.action = form.action;
    this.data = {};

    form.addEventListener('submit', e => this.handleSubmit(e));
  }
}


제출 처리기에서 navigator.onLine 속성을 사용하여 간단한 *연결 *검사를 포함할 수 있습니다. Browser support for it은 전반적으로 훌륭하고 구현하기 쉽습니다.

⚠️ 그러나 실제 인터넷 액세스가 있는 경우가 아니라 클라이언트가 네트워크에 연결되어 있는 경우에만 속성이 감지할 수 있으므로 possibility of false positives이 있습니다. 반면에 Afalse 값은 비교적 확실하게 "오프라인"을 의미한다고 신뢰할 수 있습니다. 따라서 다른 방법보다는 확인하는 것이 가장 좋습니다.

사용자가 현재 오프라인 상태인 경우 지금은 양식 제출을 보류하고 대신 데이터를 로컬에 저장합니다.

handleSubmit(e) {
  e.preventDefault();
  // parse form inputs into data object.
  this.getFormData();

  if (!navigator.onLine) {
    // user is offline, store data on device.
    this.storeData();
  } else {
    // user is online, send data via ajax.
    this.sendData();
  }
}


양식 입력 저장



사용자 장치에 임의의 데이터를 저장하는 방법에 대한 항목a few different options이 있습니다. 데이터에 따라 로컬 복사본이 메모리에 유지되지 않도록 하려면 sessionStorage를 사용할 수 있습니다. 이 예에서는 localStorage 로 이동하겠습니다.

*타임스탬프 **양식 데이터를 새 개체에 넣은 다음 localStorage.setItem를 사용하여 저장할 수 있습니다. 이 메소드는 키(id 형식)와 값(데이터의 JSON 문자열)이라는 두 가지 인수를 사용합니다.

storeData() {
  // check if localStorage is available.
  if (typeof Storage !== 'undefined') {
    const entry = {
      time: new Date().getTime(),
      data: this.data,
    };
    // save data as JSON string.
    localStorage.setItem(this.id, JSON.stringify(entry));
    return true;
  }
  return false;
}


힌트: "응용 프로그램"탭 아래 *Chrome의 *dev 도구에서 저장소를 확인할 수 있습니다. 모든 것이 계획대로 진행되면 다음과 같이 표시됩니다.

또한 사용자에게 무슨 일이 일어났는지 알리는 것도 좋은 생각입니다. 그래야만 데이터가 손실된 것이 아님을 알 수 있습니다.
일종의 피드백 메시지를 표시하도록 handleSubmit 함수를 확장할 수 있습니다.


저장된 데이터 확인



사용자가 다시 온라인 상태가 되면 저장된 제출물이 있는지 확인하려고 합니다. online 이벤트를 수신하여 연결 변경 사항을 포착하고 load 이벤트를 수신하여 페이지를 새로 고칠 수 있습니다.

constructor(form){
  ...
  window.addEventListener('online', () => this.checkStorage());
  window.addEventListener('load', () => this.checkStorage());
}


이러한 이벤트가 발생하면 저장소에서 양식의 ID와 일치하는 항목을 찾습니다. 양식이 나타내는 데이터 유형에 따라 특정 연령 미만의 제출만 허용하는 "만료 날짜"확인을 추가할 수도 있습니다. 이는 일시적인 연결 문제에 대해서만 최적화하고 사용자가 2개월 전에 입력한 데이터를 실수로 제출하는 것을 방지하려는 경우에 유용할 수 있습니다.

checkStorage() {
  if (typeof Storage !== 'undefined') {
    // check if we have saved data in localStorage.
    const item = localStorage.getItem(this.id);
    const entry = item && JSON.parse(item);

    if (entry) {
      // discard submissions older than one day. (optional)
      const now = new Date().getTime();
      const day = 24 * 60 * 60 * 1000;
      if (now - day > entry.time) {
        localStorage.removeItem(this.id);
        return;
      }

      // we have valid form data, try to submit it.
      this.data = entry.data;
      this.sendData();
    }
  }
}


마지막 단계는 데이터를 성공적으로 전송한 후 localStorage에서 데이터를 제거하여 여러 제출을 방지하는 것입니다. *ajax * 형식을 가정하면 서버에서 성공적인 응답을 받는 즉시 이를 수행할 수 있습니다. 여기서는 스토리지 객체removeItem()의 메서드를 간단히 사용할 수 있습니다.

sendData() {
  // send ajax request to server
  axios.post(this.action, this.data)
    .then((response) => {
      if (response.status === 200) {
        // remove stored data on success
        localStorage.removeItem(this.id);
      }
    })
    .catch((error) => {
      console.warn(error);
    });
}


양식 제출을 보내기 위해 ajax를 사용하지 않으려는 경우 다른 해결책은 저장된 데이터로 양식 필드를 다시 채운 다음 form.submit()를 호출하거나 사용자가 직접 버튼을 누르도록 하는 것입니다.

☝️ 참고: 양식 *검증 * 및 이 데모의 보안 토큰과 같은 일부 다른 부분은 짧게 유지하기 위해 생략했습니다. 분명히 이러한 부분은 실제 생산 준비가 된 항목에서 구현되어야 합니다. *비밀번호*또는 신용카드 데이터**와 같은 항목을 암호화되지 않은 상태로 저장하면 안 되므로 민감한 데이터를 다루는 것은 여기서 또 다른 문제입니다.
**장소 상에서.

끝까지 읽어주셔서 정말 감사합니다. 어떤 피드백이든 감사히 받겠습니다. 언제든지 저에게 연락하거나 아래에 의견을 남겨주세요.

좋은 웹페이지 즐겨찾기