为什么 HTML 验证在 Electron 中不起作用?

Why is HTML validation not working in Electron?

我已经搜索了一段时间了。我有一个 Electron(版本 13.2.2,Node v14.17.3,Chrome 92)应用程序,我想以我拥有的一种简单形式向其添加一些验证。 下面的代码是在 window 中加载的 HTML 文件的一部分。结果通过 IPC 通信传递,其他与 Electron 相关的一切工作正常。控制台日志根本不显示任何未定义或任何其他问题。 例如,当我直接在 Chrome 中打开 HTML 文件时,我得到了所需的名称,如广告所示,并且正则表达式模式应用于年份字段中的输入。但是在我的 Electron window 中,我仍然可以在不触发任何验证的情况下保存对象。在 GitHub 上搜索我发现了一个有点相似的问题(尽管我没有遇到任何其他问题,这是一个工作应用程序)但它提到它已被关闭为固定 (https://github.com/electron/electron/issues/1043)。我缺少什么才能使 requiredpattern 验证生效?

这是 HTML 形式:

    <section>
      <form action="#" method="POST" id="add-new-pattern-form">
        <label for="pattern-name">Name:</label>
        <input id="pattern-name" type="text" name="pattern-name" required />
        <p></p>
        <div id="cover-image"></div>
        <p></p>
        <button type="button" id="open-cover-image">Add Cover Image</button>
        <p></p>
        <label for="company-name">Company:</label>
        <input id="company-name" type="text" name="company-name" />
        <p></p>
        <label for="year">Year:</label>
        <input id="year" type="text" name="year" pattern="^\d{4}$" />
        <p></p>
        <label for="notes">Notes:</label>
        <textarea id="notes" name="notes" style="resize: true"></textarea>
        <p></p>
        <div id="additional-images"></div>
        <p></p>
        <button type="button" id="add-images">Add Images</button>
        <p></p>
        <input
          id="submit-new-pattern-button"
          type="submit"
          value="Save Pattern"
        />
      </form>
    </section>

这是渲染器中的用法:

submitNewPatternButton.addEventListener("click", () => {
  console.log("addnewrenderer - click submit new pattern button");
  let pattern = createPatternObjectFromInputs();
  ipcRenderer.send("submit-new-pattern-button-clicked", pattern);
});

另一个相关数据是window主进程中的设置:

const createNewWindow = (fileLocation, id) => {
  let x, y;
  const currentWindow = BrowserWindow.getFocusedWindow();

  // When we already have a window we open a new one to the right and down of the current one
  if (currentWindow) {
    const [currentWindowX, currentWindowY] = currentWindow.getPosition();
    x = currentWindowX + 20;
    y = currentWindowY + 20;
  }

  let newWindow = new BrowserWindow({
    x,
    y,
    webPreferences: {
      preload: path.join(__dirname, "preload.js"),
    },
    show: false,
  });

  newWindow.loadFile(fileLocation);

  newWindow.once("ready-to-show", () => {
    newWindow.show();
  });

  // Necessary otherwise the HTML default title is always used
  newWindow.on("page-title-updated", (event) => {
    event.preventDefault();
  });

  newWindow.on("close", () => {
    windows.delete(id);
    newWindow = null;
  });

  windows.set(id, newWindow);
  console.log("main - finished new window creation for id: " + id);

  return newWindow;
};

我要补充的最后一点是,在重构代码时使用 preload.js 并设置 contextIsolation: truenodeIntegration: false(Electron 12 之后的默认值和安全最佳实践) 我注意到,当我在页面中出现错误时,验证有效。

例如,假设我在我的渲染器中引入了一个故意的错误,例如:

const x;
x.doSomething;

在这种情况下,验证有效!显然,没有别的办法:)

Note that the submit event fires on the element itself, and not on any <button> or <input type="submit"> inside it. However, the SubmitEvent which is sent to indicate the form's submit action has been triggered includes a submitter property, which is the button that was invoked to trigger the submit request.

MDN Docs

表单验证绑定到 submit 事件,该事件在表单元素上触发,因此监听提交按钮上的点击事件不会触发它。

相反,尝试监听表单触发的 submit 事件,如下所示:

const formElement = document.getElementById('myForm');
formElement.addEventListener('submit', () => {
    // Handle form submission
});