首页 >> 大全

asp.net web api 跨域问题

2023-09-06 大全 25 作者:考证青年

缘起

以前在 mvc时代,很少出现跨域问题

自从使用了 web api + (1/2)之后,开始有跨域问题了。

简单普及下跨域:

我的理解是只要是前台页面与后台服务不在同一域名下,或者同域名不同端口下,就是跨域,我做个真值表:

前端

后端

是否跨域

:3000

:3000

:3000

:2000

:3000

:5000

如果跨域,最直接的表现就如下图:

跨域问题解决方案_跨域问题产生的原因_

下面我帖上测试代码(未解决跨域问题之前):

前端:

<script type="text/javascript" src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js">script>
<script type="text/javascript">$(function () {       $("#btn2").click(function () {$.ajax({type: "POST",url: "http://localhost:4272/api/Resources/GetPrintMethod",                success: function (data) {console.log(data);},error: function (e, XMLHttpRequest, textStatus) {console.log(e);},                });});});$(function () {//.ajaxError事件定位到document对象,文档内所有元素发生ajax请求异常,都将冒泡到document对象的ajaxError事件执行处理,ajax方法中有error,先处理error,再冒泡到此处的error
        $(document).ajaxError(//所有ajax请求异常的统一处理函数,处理function (event, xhr, options, exc) {alert("StatusCode:" + xhr.status);if (xhr.status == 'undefined') {return;}switch (xhr.status) {case 403:// 未授权异常
                        alert("系统拒绝:您没有访问权限。");break;case 404:alert("您访问的资源不存在。");break;}});});
script><body>        <input type="button" value="测试跨域请求" id="btn2">
body>

View Code

后端就是一个 web api程序,我就不全贴了,只挑重点了:

目前只有一个:

using System.Collections.Generic;
using System.Threading.Tasks;
using System.Web.Http;namespace Summer.Api.Controllers
{[RoutePrefix("api/Resources")]public class ResourcesController : ApiController{[Route("GetPrintMethod")][HttpPost][HttpGet]public async Task GetPrintMethod(){var list = new List<string>{"数据1","数据2"};return Ok(new { frontPrintMethod = list });}}
}

View Code

这时,我们运行起来后端,在上打上断点:

跨域问题解决方案_跨域问题产生的原因_

然后前端请求:

首先,断点生效,似乎正常通过, Ok(.....),

But,前台却得到:

跨域问题解决方案__跨域问题产生的原因

这是前端的一个异常捕获, code是0,0是什么?这显然不是我们想要的

在我查到了一些端倪:

_跨域问题解决方案_跨域问题产生的原因

跨域问题解决方案__跨域问题产生的原因

竟然还没有调用Send方法?这是什么鬼?WTF...为什么会这样呢?

再观察下看看:

发现有1次请求,并且状态是200,照理说应当没问题了,可为什么会得到 0呢?

_跨域问题产生的原因_跨域问题解决方案

还有一行错误信息:

to load :4272/api//: No '--Allow-' is on the . 'null' is not .

先看一下详细信息再说:

_跨域问题解决方案_跨域问题产生的原因

跨域问题解决方案__跨域问题产生的原因

200,OK,竟然还得到了数据,不错,不错,可是为什么有那行错误信息呢?

那行错误信息

to load :4272/api//: No '--Allow-' is on the . 'null' is not .

这段是说被请求的资源没有允许跨域,所以不允许访问,可是奇怪,不允许访问,为什么还能得到结果呢。。。奇怪。。。不知道是不是Bug。。。。。

尝试解决

下面我来尝试解决它

既然是跨域,那就找解决方案呗,后台是,NuGet查找并安装...Cors

然后在中加上一句:

.(new .Web.Http.Cors.("*", "*", "*"));

_跨域问题解决方案_跨域问题产生的原因

再次运行请求看下,这次我们成功得到了结果,并没有报错对比下加没加跨域插件下的响应报文头:

_跨域问题解决方案_跨域问题产生的原因

我发现加了跨域插件后,响应报文头,自动加了一行:

--Allow-:*

有了它,就允许跨域了,问题似乎得到了解决。

弦外

人就是不满足,现在,我要加需求,我Api现在有了一个要求:

现在我允许了跨域,你爱是哪来哪来,我都允许,但是。。。

(据说但是之前的都是XXX)

你必须要有合法的Token,Token是什么,如何获取,如何验证它是否合法,这里不介绍。

只是我要有一个Token,随便是什么,然后,API来模拟在执行前拦截进行Token校验。

先写一个继承自,具体代码如下:

 1 using System;
 2 using System.Net;
 3 using System.Net.Http;
 4 using System.Threading;
 5 using System.Threading.Tasks;
 6 using System.Web;
 7 
 8 namespace Summer.Api.Providers
 9 {
10     public class MyAuthHandler : DelegatingHandler
11     {
12         protected override async Task SendAsync(HttpRequestMessage request,
13             CancellationToken cancellationToken)
14         {
15             var authHeader = request.Headers.Authorization;
16 
17             try
18             {
19                 var token = authHeader.Scheme;
20                 if (string.IsNullOrWhiteSpace(token))
21                     return request.CreateErrorResponse(HttpStatusCode.Forbidden, "invalid_grant. Token is empty.");
22             }
23 
24             catch (Exception ex)
25             {
26                 return request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex.Message, ex);
27             }
28 
29             return await base.SendAsync(request, cancellationToken);
30         }
31 }

View Code

然后把它加也加在中:

_跨域问题产生的原因_跨域问题解决方案

跨域问题解决方案__跨域问题产生的原因

在中我重写了方法,这样每当服务器在执行真正之前都会先走这个方法,我就可以在这里进行请求合法性检测了。

运行前端再次请求,依然得到了 0,和500错误,并且,跨域的问题又回来了:

_跨域问题解决方案_跨域问题产生的原因

好难缠啊,又跨域,似乎那插件没有对新加的起作用。

分析下:

500,是因为请求中没有,更加没有Token,所以我们直接返回

.(., ex., ex);

这个OK

但为什么我没有得到这500,而却得到了0?

观察下响应头:

_跨域问题解决方案_跨域问题产生的原因

呃,问题原来在这里,响应头中又没有了:

--Allow-:*

好吧,插件不起作用,我手动加上总可以了吧

中改一下:

_跨域问题产生的原因_跨域问题解决方案

再次调用查看结果:

跨域问题解决方案__跨域问题产生的原因

,That's what I .

终于得到了我想要的正确的Code问题完美解决。

尾声

回顾下过程:

1.出现跨域

2.引用Cros插件解决跨域

3.新增需求,要在执行前进行Token验证

4.新增 : 来在每一次执行前进行拦截检测

5.拦截后又出现跨域,Cros插件未对其起作用

6.手动为添加允许跨域响应头:

--Allow-:*

7.问题遭到解决

But:

为什么在没有加允许跨域时,虽然得到错误,却也得到了数据呢?

再次使用来调用

跨域问题解决方案__跨域问题产生的原因

跨域问题产生的原因__跨域问题解决方案

依然可以得到正确Code,跨域问题完美解决在 Web Api

.net Core中似乎不存在这么复杂,没有继续测试

node里,其实更加简单,只要在每次返回时加上允许跨域头即可。

关于我们

最火推荐

小编推荐

联系我们


版权声明:本站内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 88@qq.com 举报,一经查实,本站将立刻删除。备案号:桂ICP备2021009421号
Powered By Z-BlogPHP.
复制成功
微信号:
我知道了