首页 > 解决方案 > 设置 HTML 表单的自定义编码类型?

问题描述

假设我有一个 HTML 表单:

<form action="/whatever" enctype="application/x-custom" method="POST">
<input type="hidden" name="foo" value="bar"/>
<button type="submit">Go!</button>
</form>

有没有办法为enctype浏览器提供自定义算法?假设算法是:

<script>
function algo(/** HTMLFormElement */form) {
return Array
    .from(form.elements)
    .filter(e => e.type === 'hidden')
    .map(e => e.name.length + ';' + e.value.length + ';' + e.name + e.value)
    .join("\n");
}
</script>

有没有办法可以将此算法“绑定”到表单,以便浏览器遵循它来序列化表单数据并发送表单请求Content-Type: application/x-custom并将算法的结果作为请求正文?

我不是在寻找“使用 XMLHttpRequest”的答案,我只是在寻找具有自定义表单数据序列化的基于浏览器的表单提交。

标签: htmlformsserialization

解决方案


不,很遗憾,如果您想以自定义格式发送数据,则必须通过 AJAX 发送。我不得不这样做几次,这根本不是微不足道的。您的代码会因<input type="checkbox>, <select>,disabled输入和许多其他内容而失败。

就发送数据而言,假设设法正确获取数据,您希望通过 fetch 发送:

/**
 * @param {HTMLElement} form
 */
function algo(form) {
    return Array
        .from(form.elements)
        .filter(e => e.type === 'hidden')
        .map(e => e.name.length + ';' + e.value.length + ';' + e.name + e.value)
        .join("\n");
}
/**
 * 
 * @param {HTMLFormElement} form
 */
async function postData(form) {

    // Default options are marked with *
    const response = await fetch(form.action, {
        method: 'POST',
        cache: 'no-cache',
        headers: {
            'Content-Type': 'application/x-custom',
        },
        redirect: 'follow',
        body: algo(form)
    });
    window.history.pushState(null, "", form.action);
    // this is nasty, but emulates form response nicely
    // do not actually do this
    document.open();
    document.write(await response.text());
    document.close();
}

或者,拥有一个服务器端处理程序,将接收到的表单数据转换为正确的格式。


推荐阅读