1.为什么会有跨域问题?
基于浏览器同源策略(这是一种浏览器的安全保护措施),在浏览器,当发送javascript的脚本请求的时候,浏览器会检测这个javascript脚本是否是来自同一个来源,如果不是,浏览器会认为脚本是不安全的,不敢用。
同源策略:要求协议、域名、端口号、都要相同
比如说,不同域的网站不能访问 session 和 Cookies
Cookie 是服务器写入浏览器的一小段信息,只有同源的网页才能共享。但是,两个网页一级域名相同,只是二级域名不同,浏览器允许通过设置document.domain共享 Cookie。
举例来说,A网页是http://w1.example.com/a.html,B网页是http://w2.example.com/b.html,那么只要设置相同的document.domain,两个网页就可以共享Cookie。
例如:用c#写一个api程序,然后用一个js脚本调用结果,代码如下所示: **api的具体代码**:(注意是如何把返回结果转换成json格式的,需要引入Newtonsoft安装包)
[HttpGet]
[Route("GetCross")]
public string GetCrossDaminData()
{
return Newtonsoft.Json.JsonConvert.SerializeObject(
new {
id=123,
Name="特朗普",
Description="这个Api 就是专门用测试跨域问题"
});
}
js脚本的具体代码如下
$.ajax({
type: "Get",
data: {},
url: "http://localhost:5000/api/getcross",
success: function (result) {
debugger;
$("#result").text(result);
}})
运行结果会报错,这就是因为没有解决浏览器的同源策略的问题:
2.如何解决跨域问题
1.采用前端的方法:
在前端采用JSOnP的方法,可以解决同源策略的问题,但是我还没学前端,这里就先不写了。
2.用后台模拟http请求去获得api:
这个方法得配置,也挺麻烦的,也不写了
3.在服务器端声明允许跨域:(个人感觉这是三种中最简单的办法)
1.观察javascript访问失败后返回的提示,“头文件里面缺少Access-Control-Allow-Origin这样一行代码”,那么就调用ControllerBase里面的方法,在要request 的 head 里面添加一行代码。具体是 在要访问的Action里面添加一行代码(注意base的意思是调用父类的方法)
public string GetCrossDaminData()
{
base.HttpContext.Response.Headers.Add("Access-Control-Allow-Origin", "*");
//在调用的返回的head里面添加这么一行
return Newtonsoft.Json.JsonConvert.SerializeObject(
new {
id=123,
Name="特朗普",
Description="这个Api 就是专门用测试跨域问题。。"
});
}
这样就能顺利的用js文件访问了:
2.当然,如果允许跨域的问题较多时,可以使用AOP的思想,用ActionFilter的方法,添加Attribute,具体要添加的Attribute的代码如下:
public class CrossDomainFilterAttribute : Attribute, IActionFilter
{
//无论是在OnActionExecuted、OnActionExecuting 来指定跨域都可以
//但是两个方法里面不能同时都指定;
public void OnActionExecuted(ActionExecutedContext context)
{
context.HttpContext.Response.Headers.Add("Access-Control-Allow-Origin", "*");
}
public void OnActionExecuting(ActionExecutingContext context)
{
//#region 支持跨域
//context.HttpContext.Response.Headers.Add("Access-Control-Allow-Origin", "*");
//#endregion
}
这样,再在要引用的方法上,添加 Attribute 属性就行了。(过于简单,此处不再演示),如果添加到类上,就对所有的 Action 起作用,如果某个Action上不想使用,可以单独添加 [AllowAnonymous] 方法。
3.也可以使用 .net core 已经封装好的方法来实现:
3.1先引用nuget包(但是我看资料,不引用好像也可以)
中间件注册,然后使用,代码如下
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddCors(option =>
option.AddPolicy("AllowCors", _build => //F12反编译一下,声明反编译的内容
_build.AllowAnyOrigin().AllowAnyMethod()));
//上边代码的意思是,允许所有的方法都支持跨域;
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseRouting();
app.UseCors("AllowCors");//括号里面的名要和上边相对应
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
} }
这样所有的Action都支持跨域了,如果某个不想支持跨域,这个还不会,具体可以查看官方文档。
部分跨域的配置:
参考资料如感觉侵权,联系侵删。
参考资料:CSDN .Net Core 处理跨域问题