HTML表单方法是POST,但它作为OPTIONS提交[重复]

Posted

技术标签:

【中文标题】HTML表单方法是POST,但它作为OPTIONS提交[重复]【英文标题】:HTML form method is POST but it's submitting as OPTIONS [duplicate] 【发布时间】:2018-05-19 20:49:36 【问题描述】:

至少可以说,我发生了一件奇怪的事情。

提交时具有post 方法的html 表单使用options 代替,这是html 代码:

<form action="https://omitted" method="post" id="canvasForm">
    <div class="form-group" style="margin-top: 10%; text-align: center;">
        <h1>Canvas Integration</h1>
        <label style="text-align: right;" for="school_name" class="col-sm-4 control-label">School Prefix *</label>
        <div class="col-sm-10">
            <input type="text" style="margin-right: 1%; margin-bottom: 2%; width:60%" class="form-control" name="school_name" placeholder="School Prefix" tabindex="1" required>
            <!-- <i class="fa fa-question-circle" aria-hidden="true"></i> -->
        </div>
        <label style="text-align: right;" for="code" class="col-sm-4 control-label">Code *</label>
        <div class="col-sm-6" >
            <input id="code" type="text" class="form-control" style="margin-right: 1%; margin-bottom: 2%; width:60%" name="code" tabindex="1" placeholder="code" required>
        </div>
        <label style="text-align: right;" for="code" class="col-sm-4 control-label">School Canvas URL *</label>
        <div class="col-sm-6" >
            <input id="canvas_url" type="text" class="form-control" style="margin-right: 1%; margin-bottom: 2%; width:60%" name="canvas_url" tabindex="1" placeholder="school canvas url" required>
        </div>
        <label style="text-align: right;" for="clientid" class="col-sm-4 control-label">ID *</label>
        <div class="col-sm-6">
            <input type="text" class="form-control" style="margin-bottom: 2%;margin-right: 1%; width:60%" name="clientid" placeholder="ID" tabindex="1" required>
            <div class="tooltip">
                <i class="fa fa-question-circle" aria-hidden="true" >
                <img  class="tooltiptext" src="images/clientid.png" style="width: 550px"></i>
            </div>
        </div>
        <label style="text-align: right;" for="securitykey" class="col-sm-4 control-label">Key *</label>
        <div class="col-sm-6">
            <input type="text" class="form-control" style="margin-right: 1%; margin-bottom: 2%; width:60%" name="securitykey" placeholder="Key" tabindex="1" required>
            <div class="tooltip">
                <i class="fa fa-question-circle" aria-hidden="true" >
                <img  class="tooltiptext" src="images/securitykey.png" style="width: 550px"></i>
            </div>
        </div>
        <div class="col-sm-6">
            <input id="redirect_url" type="hidden" class="form-control" style="margin-right: 1%; margin-bottom: 2%; width:60%;float: center;" name="redirect_url" placeholder="Canvas URL" tabindex="1" required>
        </div>
    </div>
    <div class="form-group" style="text-align: center;">
        <div class="col-sm-offset-2 col-sm-10">
            <button type="submit" class="btn btn-primary btn-w-md" >Submit</button>
        </div>
    </div>
    <div class="form-group" style="text-align: center;">
        <div id="response" class="col-sm-offset-2 col-sm-10">
        </div>
    </div>
</form>

我有一些提交表单的 JS 代码:

    form.onsubmit = function (e) 
        // stop the regular form submission
        e.preventDefault();

        // collect the form data while iterating over the inputs
        var data = ;
        for (var i = 0, ii = form.length; i < ii; ++i) 
          var input = form[i];
          if (input.name) 
            data[input.name] = input.value;
          
        
        // construct an HTTP request
        var xhr = new XMLHttpRequest();
        xhr.open(form.method, form.action, true);
        xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');

        // send the collected data as JSON
        xhr.send(JSON.stringify(data));

        xhr.onloadend = function (response) 
          console.log('response from server',response);
          var responseHtml = document.getElementById('response');
          if(response.target.status==400)
             responseHtml.innerHTML = '<div id="response" class="alert alert-success" role="alert" >' + response.target.response +'. Please contact edquire support team at support@edquire.com.' + '</div>';
           else if (response.target.status==200) 
             responseHtml.innerHTML = '<div id="response" class="alert alert-success" role="alert" >' + response.target.response +'! Your Canvas resource is successfully connected with us :)' + '</div>';
           else 
             responseHtml.innerHTML = '<div id="response" class="alert alert-success" role="alert" >' + 'Something went wrong :( Please Try Again!' + '</div>';
          
        ;
    ;

当我提交它时,我可以看到它正在使用 options 并且它没有传递输入字段(查看下面的屏幕截图)

【问题讨论】:

这是由于跨域资源共享 (CORS) 见developer.mozilla.org/en-US/docs/Web/HTTP/… 是的,谢谢@JaromandaX !!! 这就是为什么当我通过邮递员进行测试时它可以工作但不能从 HTML 表单进行测试,这现在很有意义 cors 标头,你有没有费心调查 Phil 的链接? 【参考方案1】:

这就是 CORS 的工作原理。您正在向远程主机提交 POST 请求。首先你的浏览器提交一个 OPTIONS 请求来检查远程主机是否接受来自其他主机的 HTTP 请求。如果是,则 POST 请求将在之后提交。

【讨论】:

“首先你的浏览器提交一个 OPTIONS 请求来检查远程主机是否接受来自其他主机的 HTTP 请求” pre-flight request 的用途跨度> 详细来说,如果 OP 没有更改请求的 content-type 标头,则不会有 pre-flight OPTIONS 请求。对远程资源的访问始终Access-Control-Allow-Origin 响应标头(如果有)确定【参考方案2】:

对于 REST 客户端,每个 POST 请求都后跟一个 POST。 这样做是为了验证一些事情,例如:

    是否为有效请求 是否支持该方法等

您可以在此处找到有关另一个线程的更多信息: What is the reason behind using OPTION request before POST on CORS requests?

【讨论】:

以上是关于HTML表单方法是POST,但它作为OPTIONS提交[重复]的主要内容,如果未能解决你的问题,请参考以下文章

POST 方法自动转换为 OPTIONS

使用POST方法将数据从表单插入mysql

HTML 表单 POST 到 WCF 服务

JavaScript POST fetch 作为 OPTIONS 发送

HTTP POST 变成 OPTIONS AngularJS

使用 post 方法提交表单后,表单数据附加到 php 中的 url 为啥?