假设有一简单架构分为前后两部分,其一是Angular构成的前端页面站点,另一个则是通过ASP.NET Web API搭建的后端服务站点。两个站点因为分别布署,所有会有CORS(Cross-Origin Resource Sharing)的问题。

再假设后端已经对此做好相应配置,比如在web.config里加上了:

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

那么当前端调用后端接口:

  save(data: any) : Observable<any> {
return this.http.post(`${this.apiUrl}`, data)
}

后端对应接口内的逻辑理论上应该是能够被正常执行的:

  [HttpPost]
[Route("api/save")]
public HttpResponseMessage Save(SomeModel model)
{
//内部逻辑
}

但结果是出现了Message:"The requested resource does not support http method 'OPTIONS'."错误。

产生此问题的原因在于HttpClient的post方法默认是采用application/json的内容类型(Content-Type)。

而CORS规范中有两种类型:

  • Simple requests
  • Preflighted requests

前者无需额外的处理,但对于内容类型的支持,仅限三种:

  • application/x-www-form-urlencoded
  • multipart/form-data
  • text/plain

对于除此以外的内容类型,比如application/json,CORS会以预检请求方式(Preflighted requests)处理。

Preflighted requests要求必须首先使用OPTIONS方法发起一个预检请求到服务器,以获知服务器是否允许该实际请求。

而在上面的后端服务代码中并没有准备相应的处理OPTIONS请求的接口,所以才会有这样的错误。

对应修正方法很简单,在同一接口方法上加上处理OPTIONS请求的逻辑:

  [HttpOptions, HttpPost]
[Route("api/save")]
public HttpResponseMessage Save(SomeModel model)
{
if (Request.Method == HttpMethod.Options) return new HttpResponseMessage(HttpStatusCode.OK);
//内部逻辑
}

有关CORS的详细描述,建议参考官方文档——Cross-Origin Resource Sharing (CORS)

Web API对application/json内容类型的CORS支持的更多相关文章

  1. ASP.NET Core Web APi获取原始请求内容

    前言 我们讲过ASP.NET Core Web APi路由绑定,本节我们来讲讲如何获取客户端请求过来的内容. ASP.NET Core Web APi捕获Request.Body内容 [HttpPos ...

  2. 【ASP.NET Web API教程】6.2 ASP.NET Web API中的JSON和XML序列化

    谨以此文感谢关注此系列文章的园友!前段时间本以为此系列文章已没多少人关注,而不打算继续下去了.因为文章贴出来之后,看的人似乎不多,也很少有人对这些文章发表评论,而且几乎无人给予“推荐”.但前几天有人询 ...

  3. Asp.Net Web API 2第十三课——ASP.NET Web API中的JSON和XML序列化

    前言 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok/p/3446289.html 本文描述ASP.NET W ...

  4. 说说Web API数据格式化——Json

    题外话 一同事离职了,我去上厕所的路上正巧碰到他办完离职手续出来,抱着他的全部家当,最值钱的可能就是那个两块钱的蓝色杯子和手中的雨伞了.在一块儿走向厕所的长长楼道里,我对他说:丫的,你是不是找到别的发 ...

  5. ASP.NET Web API中的JSON和XML序列化

    ASP.NET Web API中的JSON和XML序列化 前言 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok ...

  6. Web Api 中返回JSON的正确做法

    在使用Web Api的时候,有时候只想返回JSON:实现这一功能有多种方法,本文提供两种方式,一种传统的,一种作者认为是正确的方法. JSON in Web API – the formatter b ...

  7. Web Api 中返回JSON的正确做法(转)

    出处:http://www.cnblogs.com/acles/archive/2013/06/21/3147667.html 在使用Web Api的时候,有时候只想返回JSON:实现这一功能有多种方 ...

  8. ASP.NET Web API 通过参数控制返回类型(JSON|XML)

    一个很实用的技巧,可以在访问web api服务的时候指定返回数据的格式类型,比如 json 或者 xml. 因为 web api 默认返回的是XML格式,但是现在json 比较流行,同时网上也有其他的 ...

  9. SpringMVC如何接收application/json内容编码类型的参数?

    在上代码之前,有必要先说说@ResquestBody注解的含义: 1.官方解释如下: Annotation indicating a method parameter should be bound ...

随机推荐

  1. Hibernate(三): org.hibernate.HibernateException: No CurrentSessionContext configured!

    Hibernate版本5.2.9 获取Session的方式是sessionFactory.getCurrentSession(); 比较老一些的版本使用的是sessionFactory.openSes ...

  2. Centos:如何查找安装的jdk的目录

    使用$JAVA_HOME的话能定位JDK的安装路径的前提是配置了环境变量$JAVA_HOME,否则如下所示,根本定位不到JDK的安装路径. 正确的方式是通过 which java: [tt@vddd ...

  3. if__name__ == '__main__'

    # a.py import b def x(): print('x') b.y #b.py import a def y(): print('y') a.x() #执行b.py引发异常 首先,执行b. ...

  4. 【Android】Android Studio3.1 Mac版本设置项目桌面icon

    近来项目处于测试阶段,工作少了许多,就装了个最新的Android Studio,想写一下安卓.新建好项目,想设置个桌面的icon.我先准备好自己的icon图片,然后复制粘贴到res/mipmap-hd ...

  5. 文件上传详解 (HTML FILE)

    FileUpload 对象 在 HTML 文档中 <input type="file"> 标签每出现一次,一个 FileUpload 对象就会被创建. 该元素包含一个文 ...

  6. java中包的定义

    对包中的java程序进行编译(cmd) 编译:javac -d . Test.java 执行:java com.java.demo.Test package com.java public class ...

  7. [LeetCode] Count Different Palindromic Subsequences 计数不同的回文子序列的个数

    Given a string S, find the number of different non-empty palindromic subsequences in S, and return t ...

  8. [LeetCode] Split Concatenated Strings 分割串联字符串

    Given a list of strings, you could concatenate these strings together into a loop, where for each st ...

  9. DDD实战进阶第一波(六):开发一般业务的大健康行业直销系统(实现产品上下文仓储与应用服务层)

    前一篇文章我们完成了产品上下文的领域层,我们已经有了关于产品方面的简单领域逻辑,我们接着来实现产品上下文关于仓储持久化与应用层的用例如何来协调 领域逻辑与仓储持久化. 首先大家需要明确的是,产品上下文 ...

  10. [HNOI2011]卡农

    题目描述 众所周知卡农是一种复调音乐的写作技法,小余在听卡农音乐时灵感大发,发明了一种新的音乐谱写规则.他将声音分成 n 个音阶,并将音乐分成若干个片段.音乐的每个片段都是由 1 到 n 个音阶构成的 ...