因爲前段時間項目需求,須要用到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