因为前段时间项目需求,须要用到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