调用 WebAPI 时,请求的资源上不存在 Access-Control-Allow-Origin 标头

Posted

技术标签:

【中文标题】调用 WebAPI 时,请求的资源上不存在 Access-Control-Allow-Origin 标头【英文标题】:No Access-Control-Allow-Origin header is present on the requested resource when calling WebAPI 【发布时间】:2015-10-29 22:52:19 【问题描述】:

我正在尝试调用我的 WebAPI,但我总是收到错误 No Access-Control-Allow-Origin header is present

在Using Cors的文章之后,我们有下面的代码,但它总是落在onerror方法

// Create the XHR object.
function createCORSRequest(method, url) 
    var xhr = new XMLHttpRequest();
    if ("withCredentials" in xhr) 
        // XHR for Chrome/Firefox/Opera/Safari.
        xhr.open(method, url, true);
     else if (typeof XDomainRequest != "undefined") 
        // XDomainRequest for IE.
        xhr = new XDomainRequest();
        xhr.open(method, url);
     else 
        // CORS not supported.
        xhr = null;
    
    return xhr;


// Helper method to parse the title tag from the response.
function getTitle(text) 
    return text.match('<title>(.*)?</title>')[1];


// Make the actual CORS request.
function makeCorsRequest() 
    // All html5 Rocks properties support CORS.
    var url = 'http://localhost:56280/api/Meta/GetListMetas';    
    var xhr = createCORSRequest('GET', url);
    xhr.withCredentials = true;
    if (!xhr) 
        alert('CORS not supported');
        return;
    

    // Response handlers.
    xhr.onload = function () 
        var text = xhr.responseText;
        var title = getTitle(text);
        alert('Response from CORS request to ' + url + ': ' + title);
    ;

    xhr.onerror = function () 
        alert('Woops, there was an error making the request.');
    ;

    xhr.send();

我也尝试了JSONP,但又没有成功,落在error 方法

    $.ajax(
        type: "GET",
        dataType: 'jsonp',
        url: "http://localhost:56280/api/Meta/GetListMetas"
    ).success(function (data) 
          alert(data)
    ).error(function (da) 
    );

WebAPI

我做了一个非常简单的 API 来做示例​​p>

WebApiConfig.cs

public static class WebApiConfig

    public static void Register(HttpConfiguration config)
    
        // Web API configuration and services
        config.EnableCors();

        // Web API routes
        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/controller/id",
            defaults: new  id = RouteParameter.Optional 
        );
    

控制器

    [EnableCors(origins: "*", headers: "*", methods: "*")]
    public class MetaController : ApiController
    
        public string GetListMetas()        
        
           return "1";
        
    

我也尝试序列化返回,但没有成功。

有人可以帮助我吗?

更新

下面,我附上请求头

【问题讨论】:

当您调用api/Meta/GetListMetas 时,您是否使用过 Chrome 的开发者工具(或类似的 IE/FF/Safari)来查看您从服务器获得的响应包括标题 @tacos_tacos_tacos 我用可以看到标头请求的图像更新了我的问题。 【参考方案1】:

正如Vaughn Okerlund 提到的,问题出在客户端的请求中。 该请求被服务器阻止,因为它无法识别客户端的请求。

您可以enabled将客户端运行所在域的域列入白名单:

public static void Register(HttpConfiguration config)

    var corsAttr = new System.Web.Http.Cors.EnableCorsAttribute("http://localhost:7185", "*", "*");
    config.EnableCors(corsAttr);

    config.MapHttpAttributeRoutes();

    config.Routes.MapHttpRoute(
        name: "DefaultApi",
        routeTemplate: "api/controller/id",
        defaults: new  id = RouteParameter.Optional 
    );

如您所见,我已启用来自该域的每个动词的所有请求:

http://localhost:7185

如果你在那里配置你不需要的所有东西

[EnableCors(origins: "*", headers: "*", methods: "*")]

在您的控制器上。

考虑到您的客户端托管在 http://localhost:7185/ 中,您可以使用 jQuery 简单地使用以下语法调用服务器:

$.ajax(
    type: 'GET',
    url: 'http://localhost:56280/api/Meta/GetListMetas',
    data: ,
    dataType: "json",
    // crossDomain: true,
    success: function (result) 
        alert(result);
    ,
    //complete: function (jqXHR, textStatus) 
    //,
    error: function (req, status, error) 
        alert(error);
    
);

【讨论】:

【参考方案2】:

查看here,问题似乎在于,在控制器对服务请求的响应中,您发送的是源的通配符标头 (*),而不是指定要允许的域。为了发送凭据请求,服务器必须授予对特定域的访问权限:

重要提示:在响应凭据请求时,服务器必须指定域,并且不能使用通配符。如果标头通配符为:Access-Control-Allow-Origin: *,上述示例将失败。由于 Access-Control-Allow-Origin 明确提及 http://foo.example,因此将凭证识别内容返回给调用 Web 内容。请注意,在第 22 行中,设置了另一个 cookie。

【讨论】:

@VaughnOkerlung 我看到了一些奇怪的东西,按照你回答中的文章,它工作正常,通过 onLoad 方法。

以上是关于调用 WebAPI 时,请求的资源上不存在 Access-Control-Allow-Origin 标头的主要内容,如果未能解决你的问题,请参考以下文章

c# Web Api 启用了 CORS 并且请求的资源上不存在可怕的 No 'Access-Control-Allow-Origin' 标头

Angular2:http.get 返回“请求的资源上不存在‘Access-Control-Allow-Origin’标头。”

跨域 WebAPI 批量请求

Angular JS Cors 请求的资源上不存在“Access-Control-Allow-Origin”标头错误

来自角度 4 的 Owin 令牌调用 请求的资源上不存在“Access-Control-Allow-Origin”标头

OData 和 WebAPI:模型上不存在导航属性