zoukankan      html  css  js  c++  java
  • WebApi跨域的解决方法

          由于前段时间项目需求,需要用到WebApi跨域,我在网上也查阅很多这方面的资料,但是最终还是决定自己写一篇记录一下。

          当一个请求url的协议、域名、端口三者之间任意一与当前页面地址不同即为跨域。

          先说明一下出现跨域的原因:

          同源策略:出于安全考虑,浏览器会限制脚本中发起的跨站请求,浏览器要求JavaScript或Cookie只能访问同域下的内容。

          关于这方面的说明网上有很多,这里只是大概说明一下。

          我在这里解决这个问题的方法是使用CORS(Cross-Origin Resource Sharing 跨源资源共享):

          首先,新建一个MVC项目和WebApi项目,如图:

     接着在WebApiCors项目的Models中添加一个类Product

    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
  • 相关阅读:
    使用mongo shell和客户端连接至MongoDB Atlas
    mongo connect BI 连接至Power BI
    react native android应用启动画面
    react native android 上传文件,Nodejs服务端获取上传的文件
    react native 增加react-native-storage
    html页面pc显示正常,在手机端适配也可以看整个页面
    如何外部访问你的本地网站natapp
    百分比圆角
    json相关知识
    indexOf用法
  • 原文地址:https://www.cnblogs.com/kingleo/p/8493329.html
Copyright © 2011-2022 走看看