由于 CORS,Angular 请求无法访问 API 控制
Posted
技术标签:
【中文标题】由于 CORS,Angular 请求无法访问 API 控制【英文标题】:Angular Request Can't Access API Control due to CORS 【发布时间】:2020-01-07 07:35:04 【问题描述】:我有一个简单地上传个人资料图片的端点。尽管我启用了 CORS,但前端团队一直告诉我,由于以下错误,他们无法到达该端点:
zone.js:2990 从源 'http://localhost:4200' 访问 XMLHttpRequest 在 'http://localhost:4200' 已被 CORS 策略阻止:对预检请求的响应未通过访问控制检查:它没有 HTTP ok 状态.
他们正在 Angular 上开发。另一方面,移动团队(在 Xamarin 上开发)在达到该端点时没有任何问题。下面是我对 API 控制器的细分。
[EnableCors(origins: "*", headers: "*", methods: "*")]
public class BaseController : ApiController
//common methods used on every controller written here
而且,这里是包含图片上传方法的端点:
public class ImageController : BaseController
[IdentityBasicAuthentication]
[Authorize]
public HttpResponseMessage PostAccountPicture()
//some code here
首先,这些 [Authorize]
和 [IdentityBasicAuthentication]
标头被放置在 ImageController
的顶部,但我读到这种情况最终可能会混合请求管道,所以我将它们移到了操作的顶部(没有解决不了问题)。
我的 web.config 上也有这些 customHeader 行:
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Credentials" value="true"/>
<add name="Access-Control-Allow-Headers" value="Content-Type" />
<add name="Access-Control-Allow-Methods" value="GET, POST, PUT, OPTIONS" />
</customHeaders>
</httpProtocol>
而且,我的处理程序描述如下:
<handlers>
<remove name="WebDAV" />
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<!--<remove name="OPTIONSVerbHandler" />-->
<remove name="TRACEVerbHandler" />
<add name="OPTIONSVerbHandler" path="*" verb="OPTIONS" modules="ProtocolSupportModule" requireAccess="None" responseBufferLimit="4194304" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
一开始我没有name="OPTIONSVerbHandler"
。将其添加到 web.config 后,移动请求开始出现 500 Internal Server Error。
下面是我根据其他建议编辑的 Global.asax(Application_BeginRequest
开头没有包含):
public class WebApiApplication : System.Web.HttpApplication
protected void Application_Start()
GlobalConfiguration.Configure(WebApiConfig.Register);
GlobalConfiguration.Configuration.Formatters.Add(new FormMultipartEncodedMediaTypeFormatter());
protected void Application_BeginRequest(object sender, EventArgs e)
if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
HttpContext.Current.Response.Flush();
最后,我的WebApiConfig
课程如下:
public static class WebApiConfig
public static void Register(HttpConfiguration config)
config.EnableCors(new EnableCorsAttribute("*", "*", "*"));
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/controller/action/id",
defaults: new id = RouteParameter.Optional
);
我还要求我的前端伙伴与我分享她的 ajax 请求。是这样的:
$("form").submit(function(evt)evt.preventDefault(); var formData = new FormData($(this)[0]); $.ajax(
url: 'https://<our subdomain name is here>/api/Image/PostAccountPicture',
type: 'POST',
data: formData,
async: false,
cache: false,
contentType: false,
enctype: 'multipart/form-data',
processData: false,
headers: 'Authorization':'Basic ' + localStorage.getItem('currentUser') ,
success: function (response)
alert(response);
);return false;);
我在之前的项目中也启用了 CORS,在控制器类上设置 [EnableCors("*","*","*")]
并在 WebApiConfig.cs
上设置 config.EnableCors()
就足够了,而无需像 web.config 文件中那样进行上述所有其他调整.
现在,我不知道是什么让前端到达我的终点。
提前谢谢你!
【问题讨论】:
能分享一下角码吗 @EhsanKiani 感谢您的关注。我离 Angular 太远了,如果你能准确地告诉我你从 Angular 方面需要什么,我很高兴。我已经在我的问题中分享了他们的 ajax 请求 我也遇到了同样的问题,通过从我的角度请求中删除标头解决了 @EhsanKiani 但她需要通过标题区域向我发送用户令牌? 【参考方案1】:在使用 Angular 进行开发并在浏览器和后端之间使用本地服务器时,我遇到了同样的问题(以便在代码更改时即时更新 gui)。我们通过添加Allow CORS Plugin 解决了这个问题 Chrome(我想其他浏览器)不喜欢处理页面的服务器与发送 api 调用的服务器不同。
这在生产中当然没有问题,因为浏览器正在到达预期的服务器,而不是中间服务器中的一种人。
【讨论】:
遗憾的是这对我们没有帮助。我检查了我队友的chorme,它已经有了这个插件。我只是打开它并再次触发请求,但CORS错误仍然存在【参考方案2】:您可以尝试在角度端发送跨域/跨域:true 就像下面的方式 标题: '授权':'基本' + localStorage.getItem('currentUser'), '访问控制允许来源':'*', 'Access-Control-Allow-Headers':'Origin,X-Requested-With,Content-Type,Accept'
【讨论】:
现在错误变成了The 'Access-Control-Allow-Origin' header contains multiple values '*, *', but only one is allowed.
我根据您的上次更新编辑了我的朋友的 ajax,但我们收到与我上述评论相同的错误
您是否使用来自客户端的 Http 请求使用 ssl /tls 协议访问其余 api。?
是的,rest API 的 URL 以 https 开头,而 localhost 不是
那么这不是安全层通信。尝试使用具有相同标题的localhost【参考方案3】:
免责声明:仅用于开发目的。
仅在开发期间,我的 Angular 应用程序中有一个用例,我必须从外部 URL 获取模拟数据。我尝试设置标题和代理,但最终发现这个插件就像一个魅力。
试试
CORS Everywhere
Firefox 的插件/扩展。如果使用 chrome 或 edge(chromium),请查看 chrome webstore。
注意:使用风险自负。确保您了解您授予这些插件/扩展的权限类型。
仅供参考:如果链接在某个时间点失效,请尝试用谷歌搜索,呵呵。 ;)
【讨论】:
以上是关于由于 CORS,Angular 请求无法访问 API 控制的主要内容,如果未能解决你的问题,请参考以下文章
浏览器 11 | Angular 4 - CORS 请求失败(XMLHttpRequest:网络错误 0x80070005,访问被拒绝。)