添加 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 文件中的<system.webServer>
标记下添加<httpProtocol>
,如下所示:
<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中添加了<add name="Access-Control-Allow-Origin" value="*" />
,你的意思是在web.config中也添加<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" />
吗?
是的。如果您将Access-Control-Allow-Methods
和Access-Control-Allow-Headers
的这些设置添加到已设置Access-Control-Allow-Origin
的相同位置,则CORS 预检选项请求应该会成功,因此您的浏览器将继续按预期进行POST(并且浏览器将允许您的前端 JavaScript 代码访问其中的响应)
我在服务 web.config 的 <httpProtocol>
下添加了选项,如下所示:<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" />
,但它不起作用!当我删除服务调用请求中的标头选项时,它可以工作,但会向服务发送空值。我的语法正确吗?或者我把它们放在哪里是正确的?
我个人并没有像 IIS 配置那样提供足够的洞察力和经验,所以如果它不起作用,我想你可能想发布一个新的单独的特定问题,并用[iis] 或 [asp.net-mvc] 或其他任何东西——以便这里有特定专业知识的人可以为您提供更多专家帮助以上是关于添加 contentType: "application/json" 出错的主要内容,如果未能解决你的问题,请参考以下文章
Django1.10 错误:django.contrib.contenttypes.models.ContentType 未声明显式 app_label 且不在 INSTALLED_APPS 中的应用