添加 contentType: "application/json" 出错

Posted

技术标签:

【中文标题】添加 contentType: "application/json" 出错【英文标题】:Adding the contentType: "application/json" make error 【发布时间】:2018-01-24 02:37:48 【问题描述】:

我想要一个从 html 文件调用的服务。比如这样:

// POST api/values
public ActionResult Post([FromBody]Models.FormEntry[] composit)

    //Some Code here ...

    return new HttpStatusCodeResult(200);

然后我从下面的 HTML 文件中调用此服务:

<script>
    function onSubmit(form) 
        var data = $(form).serializeArray();
            $.ajax(
                type: "POST",
                url: "http://localhost:45407/api/values",
                data: JSON.stringify(data),
                dataType: "text",
                //contentType: "application/json",
                success: function ()  alert('YES!'); ,
                error: function ()  alert('NO NO NO!'); );
    
</script>

它的行为正常,但不向服务发送任何内容,composit 参数给出空值。当我取消注释 contentType: "application/json" 时,它会出错并且服务不会调用。 我通过邮递员(Chrome 扩展程序)对其进行了测试,并且效果很好。邮递员向我推荐了这个代码:

var settings = 
    "async": true,
    "crossDomain": true,
    "url": "http://localhost:45407/api/values",
    "method": "POST",
    "headers": 
        "content-type": "application/json",
        "cache-control": "no-cache",
        "postman-token": "e1b9721b-2925-c413-69e0-b1b21de239cb"
      ,
      "processData": false,
      "data": data
    

    $.ajax(settings).done(function (response) 
          console.log(response);
    );

我用我的代码替换了上面的代码,但是服务调用仍然有一个未知错误。我认为这可能是出于安全考虑,我们不允许从localhost 发送请求,为此我在服务 web.config 文件中的&lt;system.webServer&gt; 标记下添加&lt;httpProtocol&gt;,如下所示:

<httpProtocol>
  <customHeaders>
  <add name="Access-Control-Allow-Origin" value="*" />
  <add name="Access-Control-Allow-Methods" value="POST,GET,OPTIONS,PUT,DELETE" />
  <add name="Access-Control-Allow-Headers" value="Origin, X-Requested-With, Content-Type, Accept, soapaction" />
  </customHeaders>
</httpProtocol>

对于这个问题,我看到了这个链接:

contentType: 'application/json' with POST method (javascript)

Jquery JQGrid breaks when contentType=application/json?

AJAX POST call with application/json contentType gets “no 'Access-Control-Allow-Origin' header” error

那么如何通过设置真正的 Content Type 从 HTML 文件调用 Restful 服务并在请求正文中发送 JSON 数组?

【问题讨论】:

【参考方案1】:

向浏览器发送标头是服务器的工作。 ajax 调用是客户端请求。您无需在其上发送标头。实际上,您可以返回类型可以是 'json'。你不需要serializeArray,serialize函数就可以了

post 请求的简写形式如下:

$.post('http://localhost:45407/api/values',
    $('#formId').serialize(), function(response)
         //callback body
    , 'json');

现在在服务器端,您需要进行一些更改 在发送响应之前设置标题'application/json' 如果这是一个跨域请求 ajax 调用将不起作用。您必须将请求域列入白名单。

header('Access-Control-Allow-Origin: *');  

您可以使用任何特定的 url 而不是使用“*”。如果所有请求来自资源存在的域之外,则此通配符实际上允许所有请求有效。

【讨论】:

根据我的描述,我在服务web.config之前添加了这个header选项。你的意思是,我必须把它放在其他地方吗?【参考方案2】:

添加 content-type: application/json 请求标头会触发您的浏览器执行 CORS 预检 OPTIONS 请求。

https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS 有更多详细信息。

那么如何通过设置真正的 Content Type 从 HTML 文件调用 Restful 服务并在请求正文中发送 JSON 数组?

您需要为http://localhost:45407/api/values 端点配置服务器以发送Access-Control-Allow-Methods 响应标头,其中包含Content-Type 的值。

具体操作方式取决于正在运行的特定服务器后端 http://localhost:45407。但无论如何,它需要在该服务器上进行配置。您无法从客户端执行此操作。

【讨论】:

谢谢,根据我的描述,我在web.config中添加了&lt;add name="Access-Control-Allow-Origin" value="*" /&gt;,你的意思是在web.config中也添加&lt;add name="Access-Control-Allow-Methods" value="POST,GET,OPTIONS,PUT,DELETE" /&gt;&lt;add name="Access-Control-Allow-Headers" value="Origin, X-Requested-With, content-type, Accept" /&gt;吗? 是的。如果您将Access-Control-Allow-MethodsAccess-Control-Allow-Headers 的这些设置添加到已设置Access-Control-Allow-Origin 的相同位置,则CORS 预检选项请求应该会成功,因此您的浏览器将继续按预期进行POST(并且浏览器将允许您的前端 JavaScript 代码访问其中的响应) 我在服务 web.config 的 &lt;httpProtocol&gt; 下添加了选项,如下所示:&lt;add name="Access-Control-Allow-Methods" value="POST,GET,OPTIONS,PUT,DELETE" /&gt;&lt;add name="Access-Control-Allow-Headers" value="Origin, X-Requested-With, Content-Type, Accept" /&gt;,但它不起作用!当我删除服务调用请求中的标头选项时,它可以工作,但会向服务发送空值。我的语法正确吗?或者我把它们放在哪里是正确的? 我个人并没有像 IIS 配置那样提供足够的洞察力和经验,所以如果它不起作用,我想你可能想发布一个新的单独的特定问题,并用[iis] 或 [asp.net-mvc] 或其他任何东西——以便这里有特定专业知识的人可以为您提供更多专家帮助

以上是关于添加 contentType: "application/json" 出错的主要内容,如果未能解决你的问题,请参考以下文章

Django1.10 错误:django.contrib.contenttypes.models.ContentType 未声明显式 app_label 且不在 INSTALLED_APPS 中的应用

ContentType 未声明显式 app_label

Django contenttypes 应用

Jquery AJAX post提交json示例

20,Django contenttypes 应用

Django contentType