当前位置: 首页 > news >正文

C#进阶-ASP.NET的WebService跨域CORS问题解决方案

在现代的Web应用程序开发中,跨域资源共享(Cross-Origin Resource Sharing, CORS)问题是开发者经常遇到的一个挑战。特别是当前端和后端服务部署在不同的域名或端口时,CORS问题就会显得尤为突出。在这篇博客中,我们将深入探讨如何在 .NET WebService 中解决CORS问题,帮助开发者顺利实现跨域请求。


一、CORS问题描述

在Web应用中,浏览器安全机制通常会阻止来自不同域的请求,这被称为“同源策略”。同源策略允许同一来源(协议、主机和端口相同)的资源相互访问,但会阻止不同来源的资源访问。这种机制虽然提高了安全性,但在实际开发中,前端和后端通常会部署在不同的服务器上,这就引发了CORS问题。

举个例子,当你试图从 http://frontend.com 发送一个请求到 http://api.backend.com 时,浏览器会拦截这个请求并抛出一个CORS错误:

Access to XMLHttpRequest at 'http://api.backend.com/resource' from origin 'http://frontend.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

对于 .NET WebService ,如果前端应用尝试从另一个域名访问服务,而服务端没有适当的CORS策略,那么浏览器会阻止这些请求并显示该跨域错误。


二、CORS问题代码示例

为了更好地理解CORS问题及其解决方案,让我们先创建一个简单的前后端交互的.NET WebService示例。

1. 后端WebService接口代码

首先,创建一个新的 .NET Framework 项目。你可以使用 Visual Studio 或者命令行工具(如 dotnet CLI )来创建项目。在项目中,我们定义一个 .asmx 文件,并在 .asmx.cs 文件里创建一个接口。

在这里插入图片描述
在这里插入图片描述

接口代码如下:

using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Data;
using System.Web;
using System.Web.Services;namespace TestProject
{[WebService(Namespace = "http://tempuri.org/")][WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)][System.ComponentModel.ToolboxItem(false)][System.Web.Script.Services.ScriptService]public class Test : WebService{[WebMethod]public void GetJsonData(){string json = "{\"MapPoints\":[{\"Coordinates\":[\"118.87220827635\",\"34.885061248714\"],\"Speed\":\"45.7\",\"Time\":\"2024-05-13T13:02:09\"}]}";HttpContext.Current.Response.ContentType = "application/json";HttpContext.Current.Response.Write(json);}}
}

这个控制器有一个GET方法,当请求 http://localhost:80/Test.asmx/GetJsonData 时,它会返回一个串JSON数据。

这里我们可以用 Postman 测试代码,正确返回结果,则验证后端接口代码没有问题。

在这里插入图片描述


2. 前端接口请求代码

这里我使用的前端访问接口的JavaScript代码是基于 axios 实现的。

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>CORS Test</title>
</head><body><h1>CORS Test</h1><button id="fetchDataButton">Fetch Data</button><script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script><script>document.getElementById('fetchDataButton').addEventListener('click', function () {getCarLocation();});function getCarLocation() {axios.get('http://localhost:80/Test.asmx/GetJsonData').then(function (response) {console.log('Success:', response.data);}).catch(function (error) {console.error('Error:', error);});}</script>
</body></html>

页面效果图如下:
在这里插入图片描述

当点击 Fetch Data 按钮时,页面会访问 http://localhost:80/Test.asmx/GetJsonData 接口,并输出返回值到F12控制台日志里。

此时,如果我们不配置CORS,那么请求会被拦截,并报错:

Access to XMLHttpRequest at 'http://localhost:80/Test.asmx/GetJsonData' from origin 'http://localhost:8080' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

三、CORS配置详细步骤

为了让我们的 WebService 支持跨域请求,我们需要在项目中配置CORS。在 .NET Framework 中,我们可以通过如下步骤来配置CORS。

1. 配置Global.asax全局请求头参数

创建或打开项目的 Global.asax 文件,找到或添加 Application_BeginRequest() 方法,添加响应头参数,其中 <"Access-Control-Allow-Origin", "*"> 这个响应头是最重要的。


namespace TestProject
{public class Global : System.Web.HttpApplication{protected void Application_BeginRequest(){HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept, Authorization, X-Requested-With");if (HttpContext.Current.Request.HttpMethod == "OPTIONS"){HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "86400");HttpContext.Current.Response.StatusCode = 204; HttpContext.Current.Response.End();}}}
}

要非常注意的是,每个请求头参数只能添加一次,如果重复添加,依然会访问报错,可以排查一下 web.config 文件或者专门的路由模块有没有已经添加,或者再每次添加之前判断当前请求头是否已经存在,如果存在删除在添加。


2. 创建自定义HTTP模块并注册

.NET Framework 中,通过自定义 HTTP 模块修改 HTTP 响应头,可以协助处理跨域问题。

我们右键解决方案,新建项目,创建 ​​CustomHttpModules​​ 模块。
在这里插入图片描述
在这里插入图片描述

模块内创建 HeaderFilterHttpModule.cs 文件。
在这里插入图片描述
代码如下 :

using System;
using System.Web;namespace CustomHttpModules
{public class HeaderFilterHttpModule : IHttpModule{public void Init(HttpApplication context){context.PreSendRequestHeaders += OnPreSendRequestHeaders;}public void Dispose(){ }void OnPreSendRequestHeaders(object sender, EventArgs e){try{HttpApplication app = sender as HttpApplication;if (app != null && app.Context != null && app.Context.Response != null){var headers = app.Context.Response.Headers;if (headers != null){headers.Remove("Server");headers.Remove("X-AspNet-Version");headers.Remove("X-AspNetMvc-Version");headers.Remove("X-Frame-Options");headers.Remove("X-Powered-By");// 添加CORS相关的头信息headers.Add("Access-Control-Allow-Origin", "*");headers.Add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");headers.Add("Access-Control-Allow-Headers", "Content-Type, Accept");}}}catch (Exception ex){// 记录异常}}}
}

创建完成后,我们到主项目注册这个自定义的 HTTP 模块。

先给主项目添加引用:

右键主项目,添加新模块到引用。
在这里插入图片描述

然后,打开 web.config 文件,找到 <configuration> 下的 <system.webServer> 标签,引入我们刚刚创建好的 HeaderFilterHttpModule 模块。

<configuration><system.webServer><modules><add name="HeaderFilterHttpModule" type="CustomHttpModules.HeaderFilterHttpModule" /></modules></system.webServer>
</configuration>

3. 测试增加CORS配置后的代码

添加上述有关CORS的配置后,我们重新启动 .NET Framework 项目,通过测试页面点击 Fetch Data 按钮,给 http://localhost:80/Test.asmx/GetJsonData 接口发送请求。

可以看到我们得到了正确的返回值。

{"MapPoints": [{"Coordinates": ["118.87220827635","34.885061248714"],"Speed": "45.7","Time": "2024-05-13T13:02:09"}]
}

.NET WebService 跨域CORS问题完美解决。


四、CORS问题解决总结

通过配置 global.asax 全局文件,创建和注册自定义 HTTP 模块,我们成功地解决了 .NET WebService 中的 CORS 问题。这种方法的关键在于拦截和修改 HTTP 响应头,添加必要的 CORS 头信息。总结如下:

  1. 修改Global.asax文件:修改 Application_BeginRequest 方法,修改全局请求头参数。
  2. 创建自定义 HTTP 模块:实现 IHttpModule 接口,并在 PreSendRequestHeaders 事件中添加或移除 HTTP 头信息。
  3. 注册 HTTP 模块:在 Web.config 文件中注册自定义的 HTTP 模块。
  4. 测试能否跨域:通过前端发送跨域请求来验证 CORS 配置是否正确。

通过这些步骤,开发者可以有效地解决跨域资源共享问题,确保前后端服务的顺畅通信。在实际开发中,根据具体项目的需求,CORS 配置可能会有所不同,但核心思想和步骤是类似的。希望这篇博客能为你解决 CORS 问题提供有价值的帮助。

相关文章:

C#进阶-ASP.NET的WebService跨域CORS问题解决方案

在现代的Web应用程序开发中&#xff0c;跨域资源共享&#xff08;Cross-Origin Resource Sharing, CORS&#xff09;问题是开发者经常遇到的一个挑战。特别是当前端和后端服务部署在不同的域名或端口时&#xff0c;CORS问题就会显得尤为突出。在这篇博客中&#xff0c;我们将深…...

如何利用TikTok矩阵源码实现自动定时发布和高效多账号管理

在如今社交媒体的盛行下&#xff0c;TikTok已成为全球范围内最受欢迎的短视频平台之一。对于那些希望提高效率的内容创作者而言&#xff0c;手动发布和管理多个TikTok账号可能会是一项繁琐且耗时的任务。幸运的是&#xff0c;通过利用TikTok矩阵源码&#xff0c;我们可以实现自…...

Java高级编程技术详解:从多线程到算法优化的全面指南

复杂度与优化 复杂度与优化在算法中的应用 算法复杂度是衡量算法效率的重要指标。了解和优化算法复杂度对提升程序性能非常关键。本文将介绍时间复杂度和空间复杂度的基本概念&#xff0c;并探讨一些优化技术。 时间复杂度和空间复杂度 时间复杂度表示算法执行所需时间随输…...

Redis 分布式锁过期了,还没处理完怎么办?

为了防止死锁&#xff0c;我们会给分布式锁加一个过期时间&#xff0c;但是万一这个时间到了&#xff0c;我们业务逻辑还没处理完&#xff0c;怎么办&#xff1f; 这是一个分布式应用里很常见到的需求&#xff0c;关于这个问题&#xff0c;有经验的程序员会怎么处理呢&#xff…...

Vue2+Element-ui后台系统常用js方法

el-dialog弹框关闭清空form表单并清空验证 cancelDialog(diaLog, formRef) {this[diaLog] falseif (formRef) {this.$refs[formRef].resetFields()} }页面使用&#xff1a; <el-dialog :visible.sync"addSubsidyDialog.dialog" close"cancelDialog(addSub…...

Kafka高频面试题整理

文章目录 1、什么是Kafka?2、kafka基本概念3、工作流程4、Kafka的数据模型与消息存储机制1)索引文件2)数据文件 5、ACKS 机制6、生产者重试机制:7、kafka是pull还是push8、kafka高性能高吞吐的原因1&#xff09;磁盘顺序读写&#xff1a;保证了消息的堆积2&#xff09;零拷贝机…...

uniapp地图自定义文字和图标

这是我的结构&#xff1a; <map classmap id"map" :latitude"latitude" :longitude"longitude" markertap"handleMarkerClick" :show-location"true" :markers"covers" /> 记住别忘了在data中定义变量…...

k8s_探针专题

关于探针 生产环境中一定要给pod设置探针&#xff0c;不然pod内的应用发生异常时&#xff0c;K8s将不会重启pod。 需要遵循以下几个原则&#xff08;本人自己总结&#xff0c;仅供参考&#xff09;&#xff1a; 探针尽量简单&#xff0c;不要消耗过多资源。因为探针较为频繁的…...

MySQL触发器基本结构

1、修改分隔符符号 delimiter $$ 可以修改成$$ //都行 2、创建触发器函数名称 create trigger 函数名 3、什么样的操作出发&#xff0c;操作那个表 after&#xff1a;......之后触发 befor&#xff1a;......之前触发 insert&#xff1a;插入被触发 update&#xff1a;修改被触…...

前缀和(一维前缀和+二维前缀和)

前缀和 定义&#xff1a; 前缀和是指某序列的前n项和&#xff0c;可以把它理解为数学上的数列的前n项和&#xff0c;而差分可以看成前缀和的逆运算。合理的使用前缀和与差分&#xff0c;可以将某些复杂的问题简单化。 用途&#xff1a; 前缀和一般用于统计一个区间的和&…...

web前端五行属性:深入探索与实战解析

web前端五行属性&#xff1a;深入探索与实战解析 在Web前端开发中&#xff0c;五行属性这一概念或许听起来有些陌生。然而&#xff0c;如果我们将其与前端开发的核心理念相结合&#xff0c;就能发现其中蕴含的深刻内涵。本文将从四个方面、五个方面、六个方面和七个方面&#…...

白酒:茅台镇白酒的酒厂社会责任与可持续发展

云仓酒庄豪迈白酒&#xff0c;作为茅台镇的品牌&#xff0c;不仅在产品品质和口感方面有着卓着的表现&#xff0c;在酒厂社会责任和可持续发展方面也做出了积极的探索和实践。 首先&#xff0c;云仓酒庄豪迈白酒注重环境保护和资源利用。酒厂在生产过程中严格控制能源消耗和排放…...

音视频开发_SDL音频播放器的实现

今天向大家介绍一下如何通过 SDL 实现一个PCM音频播放器。这是一个最简单的播放器&#xff0c;它不涉及到音频的解复用&#xff0c;解码等工作。我们只需要将音频原始数据喂给 SDL 音频接口就可以听到悦耳的声音了。在下面的列子中我将向你演示&#xff0c;使用 SDL 做这样一个…...

C语言学习系列:初识C语言

前言&#xff0c;C语言是什么 语言&#xff0c;比如中文、英语、法语、德语等&#xff0c;是人与人交流的工具。 C语言也是语言&#xff0c;不过是一种特殊的语言&#xff0c;是人与计算机交流的工具。 为什么叫C语言呢&#xff1f; 这就要从C语言的历史说起了。 一&#…...

利用反向代理编写HTTP抓包工具——可视化界面

手写HTTP抓包工具——可视化界面 项目描述语言golang可视化fynev2功能代理抓包、重发、记录 目录 1. 示例1.1 主界面1.2 开启反向代理1.3 抓包1.4 历史记录1.5 重发 2. 核心代码2.1 GUI2.1 抓包 3. 结语3.1 传送门 1. 示例 1.1 主界面 1.2 开启反向代理 1.3 抓包 1.4 历史记录…...

下拉框数据被遮挡 且 后续数据无法下拉的 解决方法

目录 前言1. 问题所示2. 原理分析3. 解决方法3.1 添加空白版2.2 调整z-index2.3 父容器的溢出属性2.4 调整样式属性4. 效果图前言 小程序使用的是Uniapp,原理都差不多,索性标题就不标注Uniapp(小程序) 对于该问题调试了一个晚上,最终解决,对此记录下来 1. 问题所示 执…...

课设--学生成绩管理系统(二)

欢迎来到 Papicatch的博客 目录 &#x1f40b;引言 &#x1f988;编写目的 &#x1f988;项目说明 &#x1f40b;产品介绍 &#x1f988;产品概要说明 &#x1f988;产品用户定位 &#x1f988;产品中的角色 &#x1f40b; 产品总体业务流程图 &#x1f40b; 产品功…...

STM32CubeMX配置-外部中断配置

一、简介 MCU为STM32G070&#xff0c;配置为上升沿触发外部中断&#xff0c;在上升沿外部中断回调函数中进行相关操作。 二、外部中断配置 查看规格书中管教描述&#xff0c;找到I/O对应的外部中断线&#xff0c;然后进行如下上升沿触发外部中断配置。 三、生成代码 调用上升沿…...

基于Vue的日程排班表 - common-schedule

原文&#xff1a;基于Vue的日程排班表 - common-schedule-CSDN博客...

SmartEDA、Multisim、Proteus大比拼:电路设计王者之争?

在电路设计领域&#xff0c;SmartEDA、Multisim和Proteus无疑是三款备受瞩目的软件工具。它们各自拥有独特的功能和优势&#xff0c;但在这场电路设计王者的竞争中&#xff0c;谁才是真正的领跑者&#xff1f;让我们深入探究这三款软件的异同&#xff0c;揭示它们各自的魅力所在…...

国防科技大学计算机基础课程笔记02信息编码

1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制&#xff0c;因此这个了16进制的数据既可以翻译成为这个机器码&#xff0c;也可以翻译成为这个国标码&#xff0c;所以这个时候很容易会出现这个歧义的情况&#xff1b; 因此&#xff0c;我们的这个国…...

Java 加密常用的各种算法及其选择

在数字化时代&#xff0c;数据安全至关重要&#xff0c;Java 作为广泛应用的编程语言&#xff0c;提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景&#xff0c;有助于开发者在不同的业务需求中做出正确的选择。​ 一、对称加密算法…...

PL0语法,分析器实现!

简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...

【HTTP三个基础问题】

面试官您好&#xff01;HTTP是超文本传输协议&#xff0c;是互联网上客户端和服务器之间传输超文本数据&#xff08;比如文字、图片、音频、视频等&#xff09;的核心协议&#xff0c;当前互联网应用最广泛的版本是HTTP1.1&#xff0c;它基于经典的C/S模型&#xff0c;也就是客…...

华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建

华为云FlexusDeepSeek征文&#xff5c;DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色&#xff0c;华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型&#xff0c;能助力我们轻松驾驭 DeepSeek-V3/R1&#xff0c;本文中将分享如何…...

大学生职业发展与就业创业指导教学评价

这里是引用 作为软工2203/2204班的学生&#xff0c;我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要&#xff0c;而您认真负责的教学态度&#xff0c;让课程的每一部分都充满了实用价值。 尤其让我…...

pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)

目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关&#xff0…...

Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)

参考官方文档&#xff1a;https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java&#xff08;供 Kotlin 使用&#xff09; 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...

Reasoning over Uncertain Text by Generative Large Language Models

https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…...

C++:多态机制详解

目录 一. 多态的概念 1.静态多态&#xff08;编译时多态&#xff09; 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1&#xff09;.协变 2&#xff09;.析构函数的重写 5.override 和 final关键字 1&#…...