`
sangei
  • 浏览: 334082 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

webapi的跨域请求

阅读更多

国内的技术方法多多少少有点问题,我在国外的论坛找到了办法

Ok. Solved the problem with the help of @martennis answer, but with a little correction.

Every things perfect, just to take care is, we need to enter following command in Package Manager Console:

Install-Package Microsoft.AspNet.WebApi.Cors –IncludePrerelease

Instead of the one shown in the link provided by, @martennis, and after that, my WebApiConfig.cswas updated as follows:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;
using System.Web.Http.Cors;

namespace WebApiRESTfulwithJSON
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // Web API configuration and services
            var cors = new EnableCorsAttribute("*", "*", "*");
            config.EnableCors(cors);

            // Web API routes
            config.MapHttpAttributeRoutes();

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

Hence, solved the problem...!!!

Now, I will able to use my web services from anywhere, calling it from mobile applications, web applications or desktop applications.

For, how to create them from scratch, I wrote my first blog on this (...inspite of being android developer, never tried to write a blog for Android :-P Anyways...)

 

 

cors的原理:

 

{Content=newStringContent("POST: Test message")};}publicHttpResponseMessagePut(){returnnewHttpResponseMessage(){Content=newStringContent("PUT: Test message")};}}}

You can run the application locally or deploy to Azure. (For the screenshots in this tutorial, I deployed to Azure App Service Web Apps.) To verify that the web API is working, navigate to http://hostname/api/test/, where hostname is the domain where you deployed the application. You should see the response text, "GET: Test Message".

Create the WebClient Project

Create another ASP.NET Web Application project and select the MVC project template. Optionally, select Change Authentication > No Authentication. You don't need authentication for this tutorial.

In Solution Explorer, open the file Views/Home/Index.cshtml. Replace the code in this file with the following:

<div><selectid="method"><optionvalue="get">GET</option><optionvalue="post">POST</option><optionvalue="put">PUT</option></select><inputtype="button"value="Try it"onclick="sendRequest()"/><spanid='value1'>(Result)</span></div>

@section scripts {
<script>// TODO: Replace with the URL of your WebService appvar serviceUrl ='http://mywebservice/api/test';function sendRequest(){var method = $('#method').val();

        $.ajax({
            type: method,
            url: serviceUrl
        }).done(function(data){
            $('#value1').text(data);}).error(function(jqXHR, textStatus, errorThrown){
            $('#value1').text(jqXHR.responseText || textStatus);});}</script>
}

For the serviceUrl variable, use the URI of the WebService app. Now run the WebClient app locally or publish it to another website.

Clicking the “Try It” button submits an AJAX request to the WebService app, using the HTTP method listed in the dropdown box (GET, POST, or PUT). This lets us examine different cross-origin requests. Right now, the WebService app does not support CORS, so if you click the button, you will get an error.

If you watch the HTTP traffic in a tool like Fiddler, you will see that the browser does send the GET request, and the request succeeds, but the AJAX call returns an error. It’s important to understand that same-origin policy does not prevent the browser from sending the request. Instead, it prevents the application from seeing the response.

Enable CORS

Now let's enable CORS in the WebService app. First, add the CORS NuGet package. In Visual Studio, from the Tools menu, select Library Package Manager, then select Package Manager Console. In the Package Manager Console window, type the following command:

Install-PackageMicrosoft.AspNet.WebApi.Cors

This command installs the latest package and updates all dependencies, including the core Web API libraries. User the -Version flag to target a specific version. The CORS package requires Web API 2.0 or later.

Open the file App_Start/WebApiConfig.cs. Add the following code to the WebApiConfig.Register method.

usingSystem.Web.Http;namespaceWebService{publicstaticclassWebApiConfig{publicstaticvoidRegister(HttpConfiguration config){// New codeconfig.EnableCors();

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

Next, add the [EnableCors] attribute to the TestController class:

usingSystem.Net.Http;usingSystem.Web.Http;usingSystem.Web.Http.Cors;namespaceWebService.Controllers{[EnableCors(origins:"http://mywebclient.azurewebsites.net", headers:"*", methods:"*")]publicclassTestController:ApiController{// Controller methods not shown...}}

For the origins parameter, use the URI where you deployed the WebClient application. This allows cross-origin requests from WebClient, while still disallowing all other cross-domain requests. Later, I’ll describe the parameters for [EnableCors] in more detail.

Do not include a forward slash at the end of the origins URL.

Redeploy the updated WebService application. You don't need to update WebClient. Now the AJAX request from WebClient should succeed. The GET, PUT, and POST methods are all allowed.

How CORS Works

This section describes what happens in a CORS request, at the level of the HTTP messages. It’s important to understand how CORS works, so that you can configure the [EnableCors] attribute correctly, and troubleshoot if things don’t work as you expect.

The CORS specification introduces several new HTTP headers that enable cross-origin requests. If a browser supports CORS, it sets these headers automatically for cross-origin requests; you don’t need to do anything special in your JavaScript code.

Here is an example of a cross-origin request. The “Origin” header gives the domain of the site that is making the request.

GET http://myservice.azurewebsites.net/api/test HTTP/1.1Referer: http://myclient.azurewebsites.net/Accept:*/*
Accept-Language: en-US
Origin: http://myclient.azurewebsites.net
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)
Host: myservice.azurewebsites.net

If the server allows the request, it sets the Access-Control-Allow-Origin header. The value of this header either matches the Origin header, or is the wildcard value “*”, meaning that any origin is allowed.

HTTP/1.1200 OK
Cache-Control:no-cache
Pragma:no-cache
Content-Type: text/plain; charset=utf-8Access-Control-Allow-Origin: http://myclient.azurewebsites.netDate:Wed,05Jun201306:27:30 GMT
Content-Length:17

GET:Test message

If the response does not include the Access-Control-Allow-Origin header, the AJAX request fails. Specifically, the browser disallows the request. Even if the server returns a successful response, the browser does not make the response available to the client application.

Preflight Requests

For some CORS requests, the browser sends an additional request, called a “preflight request”, before it sends the actual request for the resource.

The browser can skip the preflight request if the following conditions are true:

  • The request method is GET, HEAD, or POST, and
  • The application does not set any request headers other than Accept, Accept-Language, Content-Language, Content-Type, or Last-Event-ID, and
  • The Content-Type header (if set) is one of the following:
    • application/x-www-form-urlencoded
    • multipart/form-data
    • text/plain

The rule about request headers applies to headers that the application sets by calling setRequestHeader on the XMLHttpRequest object. (The CORS specification calls these “author request headers”.) The rule does not apply to headers the browser can set, such as User-Agent, Host, or Content-Length.

Here is an example of a preflight request:

OPTIONS http://myservice.azurewebsites.net/api/test HTTP/1.1Accept:*/*
Origin: http://myclient.azurewebsites.net
Access-Control-Request-Method: PUTAccess-Control-Request-Headers: accept, x-my-custom-header
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)
Host: myservice.azurewebsites.net
Content-Length: 0

The pre-flight request uses the HTTP OPTIONS method. It includes two special headers:

  • Access-Control-Request-Method: The HTTP method that will be used for the actual request.
  • Access-Control-Request-Headers: A list of request headers that the application set on the actual request. (Again, this does not include headers that the browser sets.)

Here is an example response, assuming that the server allows the request:

HTTP/1.1200 OK
Cache-Control:no-cache
Pragma:no-cache
Content-Length:0Access-Control-Allow-Origin: http://myclient.azurewebsites.netAccess-Control-Allow-Headers: x-my-custom-headerAccess-Control-Allow-Methods: PUTDate:Wed,05Jun201306:33:22 GMT

The response includes an Access-Control-Allow-Methods header that lists the allowed methods, and optionally an Access-Control-Allow-Headers header, which lists the allowed headers. If the preflight request succeeds, the browser sends the actual request, as described earlier.

Scope Rules for [EnableCors]

You can enable CORS per action, per controller, or globally for all Web API controllers in your application.

Per Action

To enable CORS for a single action, set the [EnableCors] attribute on the action method. The following example enables CORS for the GetItemmethod only.

publicclassItemsController:ApiController{publicHttpResponseMessageGetAll(){...}[EnableCors(origins:"http://www.example.com", headers:"*", methods:"*")]publicHttpResponseMessageGetItem(int id){...}publicHttpResponseMessagePost(){...}publicHttpResponseMessagePutItem(int id){...}}

Per Controller

If you set [EnableCors] on the controller class, it applies to all the actions on the controller. To disable CORS for an action, add the[DisableCors] attribute to the action. The following example enables CORS for every method except PutItem.

[EnableCors(origins:"http://www.example.com", headers:"*", methods:"*")]publicclassItemsController:ApiController{publicHttpResponseMessageGetAll(){...}publicHttpResponseMessageGetItem(int id){...}publicHttpResponseMessagePost(){...}[DisableCors]publicHttpResponseMessagePutItem(int id){...}}

Globally

To enable CORS for all Web API controllers in your application, pass an EnableCorsAttribute instance to the EnableCors method:

publicstaticclassWebApiConfig{publicstaticvoidRegister(HttpConfiguration config){var cors =newEnableCorsAttribute("www.example.com","*","*");
        config.EnableCors(cors);// ...}}

If you set the attribute at more than one scope, the order of precedence is:

  1. Action
  2. Controller
  3. Global

Set the Allowed Origins

The origins parameter of the [EnableCors] attribute specifies which origins are allowed to access the resource. The value is a comma-separated list of the allowed origins.

[EnableCors(origins:"http://www.contoso.com,http://www.example.com", 
    headers:"*", methods:"*")]

You can also use the wildcard value “*” to allow requests from any origins.

Consider carefully before allowing requests from any origin. It means that literally any website can make AJAX calls to your web API.

// Allow CORS for all origins. (Caution!)[EnableCors(origins:"*", headers:"*", methods:"*")]

Set the Allowed HTTP Methods

The methods parameter of the [EnableCors] attribute specifies which HTTP methods are allowed to access the resource. To allow all methods, use the wildcard value “*”. The following example allows only GET and POST requests.

[EnableCors(origins:"http://www.example.com", headers:"*", methods:"get,post")]publicclassTestController:ApiController{publicHttpResponseMessageGet(){...}publicHttpResponseMessagePost(){...}publicHttpResponseMessagePut(){...}}

Set the Allowed Request Headers

Earlier I described how a preflight request might include an Access-Control-Request-Headers header, listing the HTTP headers set by the application (the so-called “author request headers”). The headers parameter of the [EnableCors] attribute specifies which author request headers are allowed. To allow any headers, set headers to “*”. To whitelist specific headers, set headers to a comma-separated list of the allowed headers:

[EnableCors(origins:"http://example.com", 
    headers:"accept,content-type,origin,x-my-header", methods:"*")]

However, browsers are not entirely consistent in how they set Access-Control-Request-Headers. For example, Chrome currently includes “origin”; while FireFox does not include standard headers such as “Accept”, even when the application sets them in script.

If you set headers to anything other than “*”, you should include at least “accept”, “content-type”, and “origin”, plus any custom headers that you want to support.

Set the Allowed Response Headers

By default, the browser does not expose all of the response headers to the application. The response headers that are available by default are:

  • Cache-Control
  • Content-Language
  • Content-Type
  • Expires
  • Last-Modified
  • Pragma

The CORS spec calls these simple response headers. To make other headers available to the application, set the exposedHeaders parameter of[EnableCors].

In the following example, the controller’s Get method sets a custom header named ‘X-Custom-Header’. By default, the browser will not expose this header in a cross-origin request. To make the header available, include ‘X-Custom-Header’ in exposedHeaders.

[EnableCors(origins:"*", headers:"*", methods:"*", exposedHeaders:"X-Custom-Header")]publicclassTestController:ApiController{publicHttpResponseMessageGet(){var resp =newHttpResponseMessage(){Content=newStringContent("GET: Test message")};
        resp.Headers.Add("X-Custom-Header","hello");return resp;}}

Passing Credentials in Cross-Origin Requests

Credentials require special handling in a CORS request. By default, the browser does not send any credentials with a cross-origin request. Credentials include cookies as well as HTTP authentication schemes. To send credentials with a cross-origin request, the client must setXMLHttpRequest.withCredentials to true.

Using XMLHttpRequest directly:

var xhr =newXMLHttpRequest();
xhr.open('get','http://www.example.com/api/test');
xhr.withCredentials =true;

In jQuery:

$.ajax({
    type:'get',
    url:'http://www.example.com/api/test',
    xhrFields:{
        withCredentials:true}

In addition, the server must allow the credentials. To allow cross-origin credentials in Web API, set the SupportsCredentials property to true on the [EnableCors] attribute:

[EnableCors(origins:"http://myclient.azurewebsites.net", headers:"*", 
    methods:"*",SupportsCredentials=true)]

If this property is true, the HTTP response will include an Access-Control-Allow-Credentials header. This header tells the browser that the server allows credentials for a cross-origin request.

If the browser sends credentials, but the response does not include a valid Access-Control-Allow-Credentials header, the browser will not expose the response to the application, and the AJAX request fails.

Be very careful about setting SupportsCredentials to true, because it means a website at another domain can send a logged-in user’s credentials to your Web API on the user’s behalf, without the user being aware. The CORS spec also states that setting origins to "*" is invalid ifSupportsCredentials is true.

Custom CORS Policy Providers

The [EnableCors] attribute implements the ICorsPolicyProvider interface. You can provide your own implementation by creating a class that derives from Attribute and implements ICorsProlicyProvider.

[AttributeUsage(AttributeTargets.Method|AttributeTargets.Class,AllowMultiple=false)]publicclassMyCorsPolicyAttribute:Attribute,ICorsPolicyProvider{privateCorsPolicy _policy;publicMyCorsPolicyAttribute(){// Create a CORS policy.
        _policy =newCorsPolicy{AllowAnyMethod=true,AllowAnyHeader=true};// Add allowed origins.
        _policy.Origins.Add("http://myclient.azurewebsites.net");
        _policy.Origins.Add("http://www.contoso.com");}publicTask<CorsPolicy>GetCorsPolicyAsync(HttpRequestMessage request){returnTask.FromResult(_policy);}}

Now you can apply the attribute any place that you would put [EnableCors].

[MyCorsPolicy]publicclassTestController:ApiController{..// 

For example, a custom CORS policy provider could read the settings from a configuration file.

As an alternative to using attributes, you can register an ICorsPolicyProviderFactory object that creates ICorsPolicyProvider objects.

publicclassCorsPolicyFactory:ICorsPolicyProviderFactory{ICorsPolicyProvider _provider =newMyCorsPolicyProvider();publicICorsPolicyProviderGetCorsPolicyProvider(HttpRequestMessage request){return _provider;}}

To set the ICorsPolicyProviderFactory, call the SetCorsPolicyProviderFactory extension method at startup, as follows:

publicstaticclassWebApiConfig{publicstaticvoidRegister(HttpConfiguration config){
        config.SetCorsPolicyProviderFactory(newCorsPolicyFactory());
        config.EnableCors();// ...}}

Browser Support

The Web API CORS package is a server-side technology. The user's browser also needs to support CORS. Fortunately, the current versions of all major browsers include support for CORS.

Internet Explorer 8 and Internet Explorer 9 have partial support for CORS, using the legacy XDomainRequest object instead of XMLHttpRequest. For more information, see XDomainRequest - Restrictions, Limitations and Workarounds.

分享到:
评论

相关推荐

    ASP.NET WebApi跨域请求配置dll文件

    在实际应用中,由于同源策略的限制,WebApi默认不支持跨域请求,即一个域下的网页不能直接访问另一个域下的资源。因此,为了解决这个问题,我们需要进行跨域请求的配置。 `System.Web.Http.Cors.dll` 是ASP.NET Web...

    【C#/Web】最简单的WEB API跨域方法

    首先,确保你的项目引用了`Microsoft.AspNet.WebApi.Cors` NuGet包。然后,在`Application_Start`方法中添加以下代码: ```csharp var cors = new EnableCorsAttribute("*", "*", "*"); GlobalConfiguration....

    ASP.NETWebApi跨域请求

    ASP.NET Web API 跨域请求是Web开发中的一个重要概念,特别是在构建分布式系统和服务导向架构时。Web API,作为Microsoft提供的一种用于构建RESTful服务的技术,经常需要与不同源的前端应用进行交互,这就涉及到...

    MVC+WebAPI跨域调用.rar

    这个“MVC+WebAPI跨域调用.rar”压缩包文件提供了一个简单的示例,用于演示如何使用jQuery在MVC(Model-View-Controller)框架下调用WebAPI实现跨域通信。 **什么是MVC模式?** MVC是一种流行的设计模式,广泛应用...

    WebApi跨域访问 ASP.NET MVC4客户端 html客户端

    综上所述,WebApi跨域访问ASP.NET MVC4客户端HTML客户端主要涉及CORS机制的使用,以及在服务器端如何配置CORS策略,以及客户端如何发起跨域请求。通过理解并正确应用这些知识点,可以构建出安全且易于维护的跨域Web...

    webapi跨域处理类

    本文将详细介绍WebAPI中处理跨域请求的两种常见方法:JSONP和服务端跨域处理。 **一、JSONP (JSON with Padding)** 1. **JSONP原理**:JSONP是一种绕过同源策略的方法,它利用`&lt;script&gt;`标签可以跨域加载资源的...

    WebApi跨域访问

    WebApi跨域访问是开发基于ASP.NET WebApi和MVC应用程序时经常遇到的一个关键问题。在Web开发中,由于浏览器的同源策略限制,不同源(协议、域名或端口不同)的请求会被阻止,这被称为跨域问题。解决这个问题的技术被...

    WebApi 跨域问题解决方案:CORS

    解决WebApi跨域问题的实践步骤如下: 1. 创建一个包含MVC项目(Web)和Web API项目(WebApiCORS)的解决方案。 2. 在MVC项目中,如Home控制器的Index视图,使用Ajax向WebApiCORS发起跨域请求。 3. 在WebApiCORS项目...

    【ASP.NET编程知识】ASP.net WebAPI跨域调用问题的解决方法.docx

    7. ASP.NET WebAPI2 复杂请求跨域设置的方法介绍 在本文中,我们可以看到,解决 ASP.NET WebAPI 跨域调用问题需要了解跨域调用原理和 Web.Config 文件中的配置信息,并且需要了解 OPTION 方法调用和 VS 自建 WebAPI...

    WebApi跨域demon

    webapi跨域小demon,适合刚学者,没什么技术难点,自己测试过,跨域成功 同源策略:出于安全考虑,浏览器会限制脚本中发起的跨站请求,浏览器要求JavaScript或Cookie只能访问同域下的内容。 正是由于这个原因,...

    ASP.NET MVC Web Api 跨域访问

    在提供的压缩包文件中,`VipSoft.Demo.sln`可能包含了项目的解决方案文件,`VipSoft.Demo.v12.suo`是Visual Studio的用户选项文件,通常包含用户的个人设置,而`VipSoft.Web`和`VipSoft.WebApi`可能分别是Web层和API...

    Nginx 解决WebApi跨域二次请求以及Vue单页面的问题

    由于项目是前后端分离,API接口与Web前端 部署在不同站点当中,因此在前文当中WebApi Ajax 跨域请求解决方法(CORS实现)使用跨域处理方式处理而不用Jsonp的方式。 但是在一段时间后,发现一个很奇怪的问题,每次...

    基于CORS实现WebApi Ajax 跨域请求解决方法

    总结来说,CORS是解决Web API跨域问题的有效方法,它允许服务器通过设置响应头来控制哪些源可以访问资源,并支持多种HTTP请求方法和自定义头部。在ASP.NET Web API中,可以通过自定义处理器来轻松实现CORS支持,以...

    WebApi和访问WebApi两个项目

    WebApi提供了丰富的特性,如过滤器、依赖注入、跨域请求支持等,使得构建强大且灵活的API成为可能。 总之,WebApi是构建RESTful服务的强大工具,而HttpWebRequest则是客户端与这些服务通信的有效手段。理解并熟练...

    jQuery.ajax 跨域请求webapi设置headers的解决方案

    本文将详细介绍如何解决jQuery跨域请求WebAPI时设置headers的问题。 首先,解决跨域请求需要在服务器端进行设置。针对ASP.NET WebAPI项目,可以在`web.config`文件中修改`&lt;httpProtocol&gt;`部分,添加跨域相关的响应...

    c# WebApi Winform托管

    5. **子线程访问UI**:当WebAPI接收请求并需要更新UI时,确保使用`Control.Invoke`或`Control.BeginInvoke`在UI线程上执行更新。 6. **测试和调用API**:在Winform应用内,你可以创建测试客户端,通过HTTP请求调用...

    jsonpajax跨域请求

    "jsonp跨域请求"可能是服务器返回的示例数据,模拟了JSONP的跨域请求过程。 总结,JSONP和CORS是解决JavaScript跨域问题的两种主要方法,它们各有优缺点,适用于不同的场景。JSONP简单易用,但安全性较低;CORS则更...

    webapi跨域使用session的方法示例

    在讨论webapi跨域使用session的方法之前,我们先要了解几个关键概念,包括跨域、session和CORS(跨源资源共享)。跨域问题通常出现在浏览器的同源策略限制下,当一个域的网页尝试访问另一个域的资源时就会遇到这个...

Global site tag (gtag.js) - Google Analytics