WebApi跨域的解決方法

      因爲前段時間項目需求,須要用到WebApi跨域,我在網上也查閱不少這方面的資料,可是最終仍是決定本身寫一篇記錄一下。javascript

      當一個請求url的協議、域名、端口三者之間任意一與當前頁面地址不一樣即爲跨域。html

      先說明一下出現跨域的緣由:java

      同源策略:出於安全考慮,瀏覽器會限制腳本中發起的跨站請求,瀏覽器要求JavaScript或Cookie只能訪問同域下的內容。jquery

      關於這方面的說明網上有不少,這裏只是大概說明一下。web

      我在這裏解決這個問題的方法是使用CORS(Cross-Origin Resource Sharing 跨源資源共享):ajax

      首先,新建一個MVC項目和WebApi項目,如圖:json

 接着在WebApiCors項目的Models中添加一個類Productapi

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

namespace WebApi.Models
{
    public class Product
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Category { get; set; }
        public decimal Price { get; set; }
    }
}

 而後添加一個Controller,以下圖:跨域

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using WebApi.Models;

namespace WebApi.Controllers
{
    public class ProductController : ApiController
    {
        private static IList<Product> products = new List<Product>  
        { 
            new Product() { Id=1, Name = "蘋果", Category = "水果", Price = 3 },
            new Product() { Id=2, Name = "茄子", Category = "蔬菜", Price = 2 },
            new Product() { Id=3, Name = "牛排", Category = "肉類", Price = 30 }
        };
        public IEnumerable<Product> GetAll()
        {
            return products;
        }

        public Product GetProductById(int id)
        {
            return products.FirstOrDefault(x => x.Id == id);
        }  
    }
}

 接下來在Web項目中添加一個Controller:瀏覽器

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace Web.Controllers
{
    public class ProductController : Controller
    {
        //
        // GET: /Product/

        public ActionResult Index()
        {
            return View();
        }

    }
}

添加一個view,用於展現請求的數據:

@{
    ViewBag.Title = "Index";
}

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <script src="~/Scripts/jquery-1.10.2.min.js"></script>
    <script type="text/javascript">
        jQuery.support.cors = true;
        $(function () {
            $.ajax({
                type: 'get',
                async: false,
                url: 'http://localhost:43450/api/Product',
                data: {},
                success: function (result) {
                    var json = result;
                    for (var i = 0; i < json.length; i++) {
                        $("#products").append("<tr><td>" + (parseInt(i) + 1) + "</td><td>" + json[i].Name + "</td><td>" + json[i].Category + "</td><td>" + json[i].Price + "</td></tr>");
                    }
                }
            });
        });
    </script>
</head>
<body>
    <table id="products" cellspacing=0 cellpadding=0 border=1>
        <thead>
            <tr>
                <th>序號</th>
                <th>名稱</th>
                <th>分類</th>
                <th>價格(元)</th>
            </tr>
        </thead>
    </table>
</body>
</html>

另外,補充一下:要是項目中須要只輸出json格式的數據能夠在Global.asax文件中添加語句

GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear();

以下圖

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;

namespace WebApiCors
{
    public class WebApiApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            GlobalConfiguration.Configure(WebApiConfig.Register);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);

            //設置以JSON 格式返回數據
            GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear();
        }
    }
}

 

作好上面的準備工做下面就能夠開始請求數據。

因爲我這兩個項目的端口號並不一致,要是按照正常狀況訪問的話就會出現跨域問題,以下圖:

這是由於受到了同源策略的約束,所以不能直接訪問接口,下面經過Nuget搜索到CORS安裝,如圖

 

安裝好以後,在WebApi項目中配置,在App_Start文件夾中找到WebApiConfig.cs文件,添加語句:

config.EnableCors(new EnableCorsAttribute("*", "*", "*"));

以下圖:

EnableCorsAttribute的構造函數指定的三個參數均爲*,表示支持全部的訪問。
第一個參數表示訪問的源;第二個參數表示訪問的頭信息;第三個參數表示容許的方法,好比:HEAD、OPTIONS、DELETE、GET、POST等等。

配置好以後再次請求,結果以下圖:

    能夠看到以前出現的跨域限制的問題已經沒了。

總結一下:上面只是作了一個簡單的CORS解決跨域的實例,還不夠深刻,因爲技術有限,仍是要慢慢研究,另外看到網上有關IE8,IE9部分支持跨域問題,這個也有待研究。


參考文章:https://docs.microsoft.com/en-us/aspnet/web-api/overview/releases/whats-new-in-aspnet-web-api-21
參考文章:https://www.cnblogs.com/landeanfen/p/5177176.html
相關文章
相關標籤/搜索