服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C# - C# WebApi CORS跨域问题解决方案

C# WebApi CORS跨域问题解决方案

2022-02-25 14:11懒得安分 C#

本篇文章主要介绍了C# WebApi CORS跨域问题解决方案,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

前言:上篇总结了下webapi的接口测试工具的使用,这篇接着来看看webapi的另一个常见问题:跨域问题。本篇主要从实例的角度分享下cors解决跨域问题一些细节。

一、跨域问题的由来

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

正是由于这个原因,我们不同项目之间的调用就会被浏览器阻止。比如我们最常见的场景:webapi作为数据服务层,它是一个单独的项目,我们的mvc项目作为web的显示层,这个时候我们的mvc里面就需要调用webapi里面的接口取数据展现在页面上。因为我们的webapi和mvc是两个不同的项目,所以运行起来之后就存在上面说的跨域的问题。

二、跨域问题解决原理

cors全称cross-origin resource sharing,中文全称跨域资源共享。它解决跨域问题的原理是通过向http的请求报文和响应报文里面加入相应的标识告诉浏览器它能访问哪些域名的请求。比如我们向响应报文里面增加这个access-control-allow-origin:http://localhost:8081,就表示支持http://localhost:8081里面的所有请求访问系统资源。其他更多的应用我们就不一一列举,可以去网上找找。

三、跨域问题解决细节

下面我就结合一个简单的实例来说明下如何使用cors解决webapi的跨域问题。

1、场景描述

我们新建两个项目,一个webapi项目(下图中webapicors),一个mvc项目(下图中web)。webapi项目负责提供接口服务,mvc项目负责页面呈现。如下:

C# WebApi CORS跨域问题解决方案

其中,web与webapicors端口号分别为“27239”和“27221”。web项目需要从webapicorss项目里面取数据,很显然,两个项目端口不同,所以并不同源,如果使用常规的调用方法肯定存在一个跨域的问题。

简单介绍下测试代码,web里面有一个homecontroller

?
1
2
3
4
5
6
7
8
public class homecontroller : controller
  {
    // get: home
    public actionresult index()
    {
      return view();
    }
  }

对应的index.cshtml

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<html>
<head>
  <meta name="viewport" content="width=device-width" />
  <title>index</title>
  <script src="~/content/jquery-1.9.1.js"></script>
  <link href="~/content/bootstrap/css/bootstrap.css" rel="external nofollow" rel="stylesheet" />
  <script src="~/content/bootstrap/js/bootstrap.js"></script>
  <script src="~/scripts/home/index.js"></script>
</head>
<body>
  测试结果:<div id="div_test">
 
  </div>
</body>
</html>

index.js文件

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var apiurl = "http://localhost:27221/";
$(function () {
  $.ajax({
    type: "get",
    url: apiurl + "api/charging/getallchargingdata",
    data: {},
    success: function (data, status) {
      if (status == "success") {
        $("#div_test").html(data);
      }
    },
    error: function (e) {
      $("#div_test").html("error");
    },
    complete: function () {
 
    }
 
  });
});

webapicors项目里面有一个测试的webapi服务chargingcontroller

?
1
2
3
4
5
6
7
8
9
10
11
12
public class chargingcontroller : apicontroller
  {
    /// <summary>
    /// 得到所有数据
    /// </summary>
    /// <returns>返回数据</returns>
    [httpget]
    public string getallchargingdata()
    {
      return "success";
    }
  }

配置webapi的路由规则为通过action调用。webapiconfig.cs文件

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public static class webapiconfig
  {
    public static void register(httpconfiguration config)
    {
      // web api 路由
      config.maphttpattributeroutes();
 
      config.routes.maphttproute(
        name: "defaultapi",
        routetemplate: "api/{controller}/{action}/{id}",
        defaults: new { id = routeparameter.optional }
      );
    }
  }

2、场景测试

1)我们不做任何的处理,直接将两个项目运行起来。看效果如何

ie浏览器:

C# WebApi CORS跨域问题解决方案

谷歌浏览器:

C# WebApi CORS跨域问题解决方案

这个结果另博主也很吃惊,不做任何跨域处理,ie10、ie11竟然可以直接请求数据成功,而同样的代码ie8、ie9、谷歌浏览器却不能跨域访问。此原因有待查找,应该是微软动了什么手脚。

2)使用cors跨域

首先介绍下cors如何使用,在webapicors项目上面使用nuget搜索“microsoft.aspnet.webapi.cors”,安装第一个

C# WebApi CORS跨域问题解决方案

然后在app_start文件夹下面的webapiconfig.cs文件夹配置跨域

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public static class webapiconfig
  {
    public static void register(httpconfiguration config)
    {
      //跨域配置
      config.enablecors(new enablecorsattribute("*", "*", "*"));
 
      // web api 路由
      config.maphttpattributeroutes();
 
      config.routes.maphttproute(
        name: "defaultapi",
        routetemplate: "api/{controller}/{action}/{id}",
        defaults: new { id = routeparameter.optional }
      );
    }
  }

我们暂定三个“*”号,当然,在项目中使用的时候一般需要指定对哪个域名可以跨域、跨域的操作有哪些等等。这个在下面介绍。

ie10、ie11

C# WebApi CORS跨域问题解决方案

谷歌浏览器

C# WebApi CORS跨域问题解决方案

ie8、ie9

C# WebApi CORS跨域问题解决方案

这个时候又有新问题了,怎么回事呢?我都已经设置跨域了呀,怎么ie8、9还是不行呢?这个时候就有必要说说cors的浏览器支持问题了。网上到处都能搜到这张图:

C# WebApi CORS跨域问题解决方案

上图描述了cors的浏览器支持情况,可以看到ie8、9是部分支持的。网上说的解决方案都是internet explorer 8、9使用 xdomainrequest对象实现cors。是不是有这么复杂?于是博主各种百度寻找解决方案。最后发现在调用处指定jquery.support.cors = true;这一句就能解决ie8、9的问题了。具体是在index.js里面

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
jquery.support.cors = true;
var apiurl = "http://localhost:27221/";
$(function () {
  $.ajax({
    type: "get",
    url: apiurl + "api/charging/getallchargingdata",
    data: {},
    success: function (data, status) {
      if (status == "success") {
        $("#div_test").html(data);
      }
    },
    error: function (e) {
      $("#div_test").html("error");
    },
    complete: function () {
 
    }
  });
});

这句话的意思就是指定浏览器支持跨域。原来ie9以上版本的浏览器、谷歌、火狐等都默认支持跨域,而ie8、9却默认不支持跨域,需要我们指定一下。你可以在你的浏览器里面打印jquery.support.cors看看。这样设置之后是否能解决问题呢?我们来看效果:

C# WebApi CORS跨域问题解决方案

问题完美解决。至于网上说的cors对ie8、9的解决方案xdomainrequest是怎么回事,有待实例验证。

3)cors的具体参数设置。

上文我们使用

?
1
config.enablecors(new enablecorsattribute("*", "*", "*"));

这一句解决了跨域问题,上面说了,这种*号是不安全的。因为它表示只要别人知道了你的请求url,任何请求都可以访问到你的资源。这是相当危险的。所以需要我们做一些配置,限制访问权限。比如我们比较常见的做法如下:

配置方法一、在web.config里面

C# WebApi CORS跨域问题解决方案

然后在webapiconfig.cs文件的register方法里面

C# WebApi CORS跨域问题解决方案

配置方法二、如果你只想对某一些api做跨域,可以直接在api的类上面使用特性标注即可。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
[enablecors(origins: "http://localhost:8081/", headers: "*", methods: "get,post,put,delete")]
  public class chargingcontroller : apicontroller
  {
    /// <summary>
    /// 得到所有数据
    /// </summary>
    /// <returns>返回数据</returns>
    [httpget]
    public string getallchargingdata()
    {
      return "success";
    }
  }

四、总结

以上就是一个简单的cors解决webapi跨域问题的实例,由于博主使用webapi的时间并不长,所以很多理论观点未必成熟,如果有说的不对的,欢迎指出。也希望大家多多支持服务器之家。

原文链接:http://www.cnblogs.com/landeanfen/p/5177176.html

延伸 · 阅读

精彩推荐
  • C#聊一聊C#接口问题 新手速来围观

    聊一聊C#接口问题 新手速来围观

    聊一聊C#接口问题,新手速来围观,一个通俗易懂的例子帮助大家更好的理解C#接口问题,感兴趣的小伙伴们可以参考一下...

    zenkey7072021-12-03
  • C#C# 后台处理图片的几种方法

    C# 后台处理图片的几种方法

    本篇文章主要介绍了C# 后台处理图片的几种方法,非常具有实用价值,需要的朋友可以参考下。...

    IT小伙儿10162021-12-08
  • C#c#学习之30分钟学会XAML

    c#学习之30分钟学会XAML

    一个界面程序的核心,无疑就是界面和后台代码,而xaml就是微软为构建应用程序界面而创建的一种描述性语言,也就是说,这东西是搞界面的...

    C#教程网8812021-12-10
  • C#C#实现的文件操作封装类完整实例【删除,移动,复制,重命名】

    C#实现的文件操作封装类完整实例【删除,移动,复制,重命名】

    这篇文章主要介绍了C#实现的文件操作封装类,结合完整实例形式分析了C#封装文件的删除,移动,复制,重命名等操作相关实现技巧,需要的朋友可以参考下...

    Rising_Sun3892021-12-28
  • C#Unity3D UGUI实现缩放循环拖动卡牌展示效果

    Unity3D UGUI实现缩放循环拖动卡牌展示效果

    这篇文章主要为大家详细介绍了Unity3D UGUI实现缩放循环拖动展示卡牌效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参...

    诗远3662022-03-11
  • C#C#基础之泛型

    C#基础之泛型

    泛型是 2.0 版 C# 语言和公共语言运行库 (CLR) 中的一个新功能。接下来通过本文给大家介绍c#基础之泛型,感兴趣的朋友一起学习吧...

    方小白7732021-12-03
  • C#C#直线的最小二乘法线性回归运算实例

    C#直线的最小二乘法线性回归运算实例

    这篇文章主要介绍了C#直线的最小二乘法线性回归运算方法,实例分析了给定一组点,用最小二乘法进行线性回归运算的实现技巧,具有一定参考借鉴价值,需要...

    北风其凉8912021-10-18
  • C#浅谈C# winForm 窗体闪烁的问题

    浅谈C# winForm 窗体闪烁的问题

    下面小编就为大家带来一篇浅谈C# winForm 窗体闪烁的问题。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...

    C#教程网7962021-12-21