零、今天完成左下角的深紫色部分
image
一、为什么会出现跨域的问题
跨域问题由来已久,主要是来源于浏览器的”同源策略”。
何为同源?只有当协议、端口、和域名都相同的页面,则两个页面具有相同的源。只要网站的 协议名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 class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="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文件目录就行)
image
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的接口写法,要求很严谨
image
4、点击”通过JsonP实现跨域请求“按钮,发现已经有数据了,证明Jsonp跨域已经成功,你可以换成自己的域名试一试,但是Cors的还不行
image
三、如何达到跨域的目的——三种跨域方式 之添加请求头实现跨域
这里我没有写到代码里,是在一般处理程序里之前用到的
** 后端**
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") }
大家感兴趣可以自己实验下。有问题请留言
四、如何达到跨域的目的——三种跨域方式 之 高效CROS
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 { //.... }
image
** 4、好啦运行调试,一切正常**
作者:SAYLINING
链接:https://www.jianshu.com/p/b239c4b277ab
共同学习,写下你的评论
评论加载中...
作者其他优质文章