サイト管理人Blog

cloudfreeで「さぁ始めましょう♪」

XMLHttpRequestでPOST送信。常に保存されているtextareaをsetIntervalとAjaxで実装。

2023-12-04 記載
概要 : HTMLページで常に保存されるtextareaをAjaxで実装
Keyword : XMLHttpRequest, POST

VSCodeを常に保存される状態で使っています。MS-Officeをはじめ、これまではファイルは変更して、最後に保存、あるいはときどき保存、というのが当たり前でした。なのでVSCodeを常に保存で使っていると、最初は落ち着かない感じもありました。しかし慣れると、なんてスッキリしているんだろう、こうあるべきではないか、と思うようになりました。

ウェブサイトでのセッテイングを書き換えたりするときに、サーバのテキストファイルを編集し保存する、という処理を書きますが、これもAjaxで常に保存されればよいのでは?と考えました。

以下はphp1ページのみでまとめたAjax常時保存型でjQueryなし版の
textarea⇔Textファイル更新。1秒置きに変更があれば保存送信が裏で走ります。

<?php

  //Ajax Save用
  $ajax = ($_REQUEST['ajax'] ?? '');
  if ($ajax === 'save') {
    if (!file_put_contents('./myfile.txt', $_REQUEST['text'])) {
      echo 'SAVE ERROR!!';
    }
    exit;
  }

  //初回ファイル読み出し
  function readText() {
    echo trim(htmlspecialchars(file_get_contents('./myfile.txt')));
  }
?>
<!doctype html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>TextFileAjaxSave</title>
</head>
<body>
  <div id="result">Auto Save</div>
  <form method="post" action="">
    <textarea id="text" cols="80" rows="40"><?=readText();?></textarea>
  </form>
</body>
<script>
  let mv_hasChange = false;
  const elem_text = document.getElementById('text');
  const req = new XMLHttpRequest();
  req.addEventListener('readystatechange', httpRequest_readystatechange);
  elem_text.addEventListener('input', () => { mv_hasChange = true; });
  setInterval(ajaxsaveText, 1000);

  function ajaxsaveText() {
    if (mv_hasChange) {
      //変更があった場合はAjax保存する
      req.open('POST', '');
      req.setRequestHeader('Cache-Control', 'no-cache');
      req.setRequestHeader('content-type', 'application/x-www-form-urlencoded;charset=UTF-8');
      req.send('ajax=save&text=' + encodeURIComponent(elem_text.value));
      mv_hasChange = false;
    }
  }

  function httpRequest_readystatechange() {
    //保存エラーがあった場合は表示する
    if (req.responseText.length) document.getElementById('result').innerText = req.responseText;
  }

</script>
</html>

encodeURIComponent は 値のみをくくること。
‘key=’を一緒に変換してしまうと’=’が消されてしまって、サーバ側で ! isset() になってしまいます。
(とココでハマりましたので -_-;)

投稿へのコメントは コチラ(掲示板) へお願いします。

サイト管理人Blog