由于 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,访问被拒绝。)

Angular和NodeJS阻止了跨域请求[重复]

Angular - 每个请求都被 CORS 阻止

访问 XMLHttpRequest 的问题已被 CORS 策略(Python/Angular)阻止

Angular2 Ng2文件上传CORS问题

Angular 4 前端中的 CORS 问题,Google Cloud Endpoints 运行 go API 后端