百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

.NET Core2.0 +Vue2.0 三种跨域方式比较

cac55 2024-10-11 11:01 41 浏览 0 评论

一、为什么会出现跨域的问题

跨域问题由来已久,主要是来源于浏览器的”同源策略”。

? 何为同源?只有当协议、端口、和域名都相同的页面,则两个页面具有相同的源。只要网站的 协议名protocol、 主机host、 端口号port 这三个中的任意一个不同,网站间的数据请求与传输便构成了跨域调用,会受到同源策略的限制。 ? 同源策略限制从一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的关键的安全机制。浏览器的同源策略,出于防范跨站脚本的攻击,禁止客户端脚本(如 JavaScript)对不同域的服务进行跨站调用(通常指使用XMLHttpRequest请求)。

所以说我们在web中,我们无法去获取跨域的请求,常见的就是无法通过js获取接口(这里要说下我的以前使用的经验:在同源系统下,前端js去调用后端接口,然后后端C#去调取跨域接口,这是我以前采用的办法,但是前后端分离,这个办法肯定就是不行了,因为那时候已经没有了前后端之分,是两个项目),所以我们只要合理使用同源策略,就可以达到跨域访问的目的。

二、如何达到跨域的目的——三种跨域方式 之JsonP

我自己建立了一个一个静态页面,用来模拟前端访问,具体如下步骤:

1、新建一个Html页面,使用Jquery来发送请求(文件在项目的WWW文件夹下,大家可以自己下载,或者Copy下边代码)。

一共三种跨域方法

<!DOCTYPE html>
<html>
<head>
 <meta charset="utf-8">
 <title>Blog.Core</title>
 <script src="https://cdn.bootcss.com/jquery/1.10.2/jquery.min.js"></script>
 <style>
 div {
 margin: 10px;
 word-wrap: break-word;
 }
 </style>
 <script>
 $(document).ready(function () {
 $("#jsonp").click(function () {
 $.getJSON("http://localhost:58427/api/Login/jsonp?callBack=?", function (data) {
 $("#data-jsonp").html("数据: " + data.value);
 });
 });
 $("#cors").click(function () {
 $.get("http://localhost:58427/api/Login/Token", function (data, status) {
 $("#status-cors").html("状态: " + status);
 $("#data-cors").html("数据: " + data);
 });
 });
 });
 </script>
</head>
<body>
 <h3>通过JsonP实现跨域请求</h3>
 <button id="jsonp">发送一个 GET </button>
 <div id="status-jsonp"></div>
 <div id="data-jsonp"></div>
 <hr />
 <h3>添加请求头实现跨域</h3>
 <hr />
 <h3>通过CORS实现跨域请求,另需要在服务器段配置CORE</h3>
 <button id="cors">发送一个 GET </button>
 <div id="status-cors"></div>
 <div id="data-cors"></div>
 <hr />
</body>
</html>

注意:这里一定要注意jsonp的前端页面请求写法,要求很严谨

2、将这个页面部署到自己的IIS中(拷贝到文件里,直接在iis添加该文件,访问刚刚的Html文件目录就行)

3、在我们的项目 LoginController 中,设计Jsonp接口,Core调用的接口我们已经有了,就是之前获取Token的接口GetJWTStr

     [HttpGet]
 [Route("jsonp")]
 public void Getjsonp(string callBack, long id = 1, string sub = "Admin", int expiresSliding = 30, int expiresAbsoulute = 30)
 {
 TokenModel tokenModel = new TokenModel();
 tokenModel.Uid = id;
 tokenModel.Sub = sub;
 DateTime d1 = DateTime.Now;
 DateTime d2 = d1.AddMinutes(expiresSliding);
 DateTime d3 = d1.AddDays(expiresAbsoulute);
 TimeSpan sliding = d2 - d1;
 TimeSpan absoulute = d3 - d1;
 string jwtStr = BlogCoreToken.IssueJWT(tokenModel, sliding, absoulute);
       //重要,一定要这么写
 string response = string.Format("\"value\":\"{0}\"", jwtStr);
 string call = callBack + "({"+response+"})";
 Response.WriteAsync(call);
 }

注意:这里一定要注意jsonp的接口写法,要求很严谨

4、点击”通过JsonP实现跨域请求“按钮,发现已经有数据了,证明Jsonp跨域已经成功,你可以换成自己的域名试一试,但是Cors的还不行

三、如何达到跨域的目的——三种跨域方式 之添加请求头实现跨域

这里我没有写到代码里,是在一般处理程序里之前用到的

后端

 public void ProcessRequest(HttpContext context)
 {
 //接收参数
 string uName = context.Request["name"];
 string data = "{\"name\":\"" + uName + "\",\"age\":\"18\"}";
 //只需在服务端添加以下两句
 context.Response.AddHeader("Access-Control-Allow-Origin", "*");
 //跨域可以请求的方式
 context.Response.AddHeader("Access-Control-Allow-Methods", "POST,GET");
 context.Response.Write(data);
 }

前端

 function ashxRequest() {
 $.post("http://localhost:5551/ashxRequest.ashx", { name: "halo" }, function (data) {
 for (var i in data) {
 alert(data[i]);
 }
 }, "json")
 }

大家感兴趣可以自己实验下。有问题请留言

四、如何达到跨域的目的——三种跨域方式 之 高效CORS

1、前端的代码在jsonp的时候已经写好,请往上看第二节,后端接口也是Token接口

剩下的就是配置跨域了,很简单!

2、在ConfigureServices中添加

       #region CORS
 services.AddCors(c =>
 {
 //↓↓↓↓↓↓↓注意正式环境不要使用这种全开放的处理↓↓↓↓↓↓↓↓↓↓
 c.AddPolicy("AllRequests", policy =>
 {
 policy
 .AllowAnyOrigin()//允许任何源
 .AllowAnyMethod()//允许任何方式
 .AllowAnyHeader()//允许任何头
 .AllowCredentials();//允许cookie
 });
 //↑↑↑↑↑↑↑注意正式环境不要使用这种全开放的处理↑↑↑↑↑↑↑↑↑↑

 //一般采用这种方法
 c.AddPolicy("LimitRequests", policy =>
 {
 policy
 .WithOrigins("http://localhost:8020", "http://blog.core.xxx.com","")//支持多个域名端口
 .WithMethods("GET", "POST", "PUT", "DELETE")//请求方法添加到策略
 .WithHeaders("authorization");//标头添加到策略
 });
 });
 #endregion

基本注释都有,大家都能看的懂,就这么简单!

3、在需要跨域的controller上,增加特性(本文因为在LoginController,所以在这个控制器里),注意名称要写对 LimitRequests

   [Produces("application/json")]
 [Route("api/Login")]
 [EnableCors("LimitRequests")]//就是这里
 public class LoginController : Controller
 {
 //....
 }

4、好啦运行调试,一切正常

至此,跨域的问题已经完成辣

五、其他跨域方法补充

nginx是一个高性能的web服务器,常用作反向代理服务器。nginx作为反向代理服务器,就是把http请求转发到另一个或者一些服务器上。

通过把本地一个url前缀映射到要跨域访问的web服务器上,就可以实现跨域访问。

对于浏览器来说,访问的就是同源服务器上的一个url。而nginx通过检测url前缀,把http请求转发到后面真实的物理服务器。并通过rewrite命令把前缀再去掉。这样真实的服务器就可以正确处理请求,并且并不知道这个请求是来自代理服务器的。

简单说,nginx服务器欺骗了浏览器,让它认为这是同源调用,从而解决了浏览器的跨域问题。又通过重写url,欺骗了真实的服务器,让它以为这个http请求是直接来自与用户浏览器的。

这样,为了解决跨域问题,只需要动一下nginx配置文件即可。

六、结语

三种办法其实都能达到目的,但是优缺点也很明显

1、手动创建JSONP跨域

优点:无浏览器要求,可以在任何浏览器中使用此方式

缺点:格式要求很严格,只支持get请求方式,请求的后端出错不会有提示,造成不能处理异常

2、添加请求头实现跨域

优点:支持任意请求方式,并且后端出错会像非跨域那样有报错,可以对异常进行处理

缺点:兼容性不是很好,IE的话 <IE10 都不支持此方式

虽然CORS的方法有点儿类似请求头,但是封装,兼容性,灵活性都要好的很多,强烈推荐。

七、初探DTOs

请看以下实体类

//数据库实体类
public class Author
{
 public string Name { get; set; }
}
public class Book
{
 public string Title { get; set; }
 public Author Author { get; set; }
}
//页面实体类
public class BookViewModel
{
 public string Title { get; set; }
 public string Author { get; set; }
}
//api调用
BookViewModel model = new BookViewModel
{
 Title = book.Title,
 Author = book.Author.Name
}

上面的例子相当的直观了,我们平时也是这么用的基本,但是问题也随之而来了,我们可以看到在上面的代码中,如果一旦在Book对象里添加了一个额外的字段,而后想在前台页面输出这个字段,那么就需要去在项目里找到每一处有这样BookViewModel转换字段的地方,这是非常繁琐的。另外,BookViewModel.Author是一个string类型的字段,但是Book.Author属性却是Author对象类型的,我们用的解决方法是通过Book.Auther对象来取得Author的Name属性值,然后再赋值给BookViewModel的Author属性,这样看起行的通,但是想一想,如果打算在以后的开发中把Name拆分成两个-FisrtName和LastName,我的天呐!我们得去把原来的ViewModel对象也拆分成对应的两个字段,然后在项目中找到所有的转换,然后替换。

那么有什么办法或者工具来帮助我们能够避免这样的情况发生呢?AutoMapper正是符合要求的一款插件。

只需一键操作,就能一劳永逸,解决所有问题,然后通过依赖注入,快速使用:

        //AutoMapper自动映射
 //Mapper.Initialize(cfg => cfg.CreateMap<BlogArticle, BlogViewModels>());
 //BlogViewModels models = Mapper.Map<BlogArticle, BlogViewModels>(blogArticle);
 BlogViewModels models = IMapper.Map<BlogViewModels>(blogArticle);//就这一句话完全搞定所有转换

今天因为时间的关系,没有说到Automapper,明天再见吧~

相关推荐

如何屏蔽色情网站?_怎么能屏蔽网站

一、基础防御:全网DNS劫持阻断1.修改全网DNS服务器推荐DNS:安全DNS:CleanBrowsing(成人内容过滤):185.228.168.168/185.228.169.168Open...

容器、Pod、虚拟机与宿主机网络通信全解:看这一篇就够了

在日常开发与部署过程中,很多人一开始都会有这样的疑惑:容器之间是怎么通信的?容器怎么访问宿主机?宿主机又如何访问容器?Kubernetes中Pod的网络和Docker容器一样吗?容器跨机器是...

Win11专业版找不到共享打印机的问题

有很多深度官网的用户,都是在办公室上班的。而上班就需要使用打印机,但更新win11系统后,却出现同一个办公室里面的打印机都找不到的问题,这该如何处理呢?其实,可能是由于我们并没有打开共享打印机而造成的...

常用电脑快捷键大全,摆脱鼠标依赖,建议收藏

Ctrl+C复制Ctrl+X剪切Ctrl+V粘贴Ctrl+Z撤销Ctrl+Y重做Ctrl+B加粗Ctrl+A全选所有文件Ctrl+S保存Ctrl+N新建Ctrl+O打开Ctrl+E...

Win11实现自动追剧Jellyfin硬解,免NAS复杂操作

大家好,欢迎来到思赞数码。本期将详细介绍如何通过安装和配置Sonarr、Radarr、Prowlarr、qBittorrent和Jellyfin,打造一套自动化的影视管理系统。很多人认为,要实现自动追...

微软Win11安卓子系统WSA 2308.40000.3.0更新推送下载

IT之家9月21日消息,微软官方博客今日宣布,已面向所有WindowsInsider用户推送了Windows11安卓子系统的2308.40000.3.0版本更新。本次更新和之前...

路由器总掉线 一个命令就能猜出八九分

明明网络强度满格或有线图标正常,但视频卡成PPT、网页刷不开、游戏动不了,闲心这些问题很多小伙伴都碰到过。每次都要开关路由、宽带/光猫、插拔网线……一通忙。有没有啥办法能快速确定故障到底在哪儿,方便处...

windows电脑如何修改hosts文件?_windows怎么修改hosts

先来简单说下电脑host的作用hosts文件的作用:hosts文件是一个用于储存计算机网络中各节点信息的计算机文件;作用是将一些常用的网址域名与其对应的IP地址建立一个关联“数据库”,当用户在浏览器中...

win10广告弹窗ShellExperienceHost.exe

win10右下角老是弹出广告弹窗,排查为以下程序引起,但是这个是系统菜单的程序不能动:C:\Windows\SystemApps\ShellExperienceHost_cw5n1h2txyewy\S...

Win10 Mobile预览版10512/10166越狱解锁部署已被黑客攻破

看起来统一的WindowsPhone和Windows越加吸引人们的关注,特别是黑客们的好奇心。XDA论坛宣称,在Win10Mobile预览版10512/10166上,已取得越狱/解锁部署突破,比如可...

6款冷门小众软件,都是宝藏,建议收藏

真的很不错(。-ω-)zzzBearhttps://bear.app/cn/Bear是一个漂亮,灵活的Markdown的写作工具。它一样只支持苹果家的全平台。它一出现就惊艳四方,就被AppSto...

如何让不符合条件的设备升级Windows 11

如果你是最近(6月24日之后)加入WindowsInsider项目并且你的设备并不符合升级条件,那么当你在尝试升级Windows11的时候可能会看到以下错误:你的PC不符合Wi...

windows host文件怎么恢复?局域网访问全靠这些!

windowshost文件怎么恢复?windowshost文件是常用网址域名及其相应IP地址建立一个关联文件,通过这个host文件配置域名和IP的映射关系,以提高域名解析的速度,方便局域网用户使用...

Mac Hosts管理工具---SwitchHosts

switchhosts!formac是一款帮助用户快速切换hosts文件的工具,switchhosts!formac能够帮助你快速方便的打造个人专用的网络环境,支持本地和在线两种方式,并且支持...

「浅谈趣说网络知识」 第十二弹 老而不死的Hosts,它还很有用

【浅谈趣说网络知识】第十二弹老而不死的Hosts,它还很有用什么时候才觉得自己真的老了,不是35岁以上的数字,不是头上的点点白发,而是不知觉中的怀旧。风口上的IT界讲的就是"长江后浪推前浪...

取消回复欢迎 发表评论: