-- 请求&已阻止跨源请求:CORS 头缺少 ‘Access-Control-Allow-Origin‘-(js,axios,vue,react等)
【官网】:无
应用场景
市面上浏览器出于安全性考虑,禁止在网页上发出请求到不同的域的web页面进行请求,此限制称为同域策略。 同域策略可阻止恶意站点读取另一个站点中的敏感数据, 但有时候,你可能想要允许其他站点对您的应用程序进行跨域请求,目前有两套解决方案,分别是:CORS(跨域资源共享) 、 jsonp。基础资源
前端跨域访问依赖后端设置
使用须知
1)Core版本中,MVC和WebApi已经合并,所以在该章节中介绍Asp.Net Core中的跨域解决方案。 2)请结合企业产品或平台的安全要求,请勿盲目放开准许跨域。应以最小限度放开。
配置步骤
【方案1-前端使用jsonp+后端输出callback回调】
<前端代码示例>
$.ajax({
url: ‘http://config.net.cn/Example/TestApi‘,
type: "get",
dataType: "jsonp",
//需要和服务端回掉方法中的参数名相对应
//注释掉这句话默认传的名称叫callback
jsonp: "CallBackForTest",
cache: false,
data: { userName: "user" },
success: function (data) {
console.log(data);
alert(data.id + "," + data.userName);
}
});
<后端代码示例>
/// <summary>
/// 原始的JSONP模式,支持(asp.net core支持,asp.net web api不支持)
/// </summary>
/// <param name="CallBackForTest"></param>
/// <param name="userName"></param>
/// <returns></returns>
[HttpGet] public dynamic GetInfor1(string CallBackForTest, string userName)
{
var data = new
{
id = userName + "01",
userName = userName
};
string callbackParams = JsonConvert.SerializeObject(data);
return $"{CallBackForTest}({callbackParams })";
}
header("Access-Control-Allow-Origin: *");
注1: 在设置header的具体过程,各个语言稍有不同,其中值*最好设置为具体的域名,比如:header("Access-Control-Allow-Origin: http://config.net.cn");
另外输出页面的话,可以设置:
<meta http-equiv="Access-Control-Allow-Origin" content="*">
注2:本质上也是设置了header头的属性。
【方案3-cors命名策略的全局拦截或action特性指定】
<step1:ConfigureService中策略的注册代码>
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
//注册跨域请求服务
services.AddCors(options =>
{
//注册一个名字为“DefaultPolicy”新策略
options.AddPolicy("DefaultPolicy", builder =>
{
builder.WithOrigins("http://localhost:1001", "http://localhost:1002") //多个地址通过"逗号"隔开
.WithMethods("GET","PUT")
.WithHeaders(Microsoft.Net.Http.Headers.HeaderNames.ContentType, "Authorization")
.AllowCredentials();
});
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
[注]补充:在core 2.x版本,AllowAnyOrigin()和AllowCredentials()可以共存,在3.x版本,不能共存,不能共存时需要指定具体的域名。 <step2:Configure全局拦截代码 或者 作用于Action的代码 >
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();
app.UseCookiePolicy();
//全局配置跨域(一定要配置在 app.UseMvc前)
//2. 命名策略
app.UseCors("DefaultPolicy");
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
[单个controller/action上指定]
/// <summary>
/// 命名策略
/// </summary>
/// <returns></returns>
[EnableCors("DefaultPolicy")]
[HttpPost]
public string Test()
{
return "来自config.net.cn上的跨域问题解决办法分享";
}
【方案4-服务端http服务程序的配置,例如:Apache等】
<apache中的设置>
在httpd.conf中,取消LoadModule headers_module modules/mod_headers.so前的注释
在<VirtualHost>中添加以下内容
Apache set ‘Access-Control-Allow-Origin’ *
重启apache即可.
常见问题
-
服务端设置 Access-Control-Allow-Origin为 *依然提示跨域
【解决方案】js客户端访问时设置了xhr.withCredentials = true时服务端必须指定具体的域名而不是*,否则无法访问
快速入门
【H5场景下cors跨域请求的封装】
function createCORSRequest(method, url) {
var xhr = new XMLHttpRequest();if ("withCredentials" in xhr) {
// 此时即支持CORS的情况
// 检查XMLHttpRequest对象是否有“withCredentials”属性
// “withCredentials”仅存在于XMLHTTPRequest2对象里
xhr.open(method, url, true);
} else if (typeof!= "undefined") {
// 否则检查是否支持XDomainRequest,IE8和IE9支持
// XDomainRequest仅存在于IE中,是IE用于支持CORS请求的方式
xhr = new XDomainRequest();
xhr.open(method, url);
} else {
// 否则,浏览器不支持CORS
xhr = null;
}
return xhr;
}
var xhr = createCORSRequest(‘GET‘, url);
if (!xhr) {
throw new Error(‘CORS not supported‘);
}