【发布时间】:2018-09-19 00:22:39
【问题描述】:
我正在使用带有 asp.net 核心后端的 Angular 2 应用程序。我正在尝试打印 pdf(下面的客户端代码)。当我在我们的开发服务器上运行时,一切正常;但是,在生产中运行我得到了
加载 api_url 失败:请求的资源上不存在“Access-Control-Allow-Origin”标头。因此不允许访问原始 url。
我所看到的所有内容都提到了有关 CORS 策略的内容,但我不明白这如何在一台服务器上正常工作,而在另一台服务器上却不行。此外,在访问其他 API 端点时,它似乎可以正常检索。
客户端api调用:
getPDF(pickupId: string): void {
this.printingSub.next(true);
this._http.get(this._dataUrl + 'pickupsheet?pickupid=' + pickupId + '&barcode=true', { responseType: ResponseContentType.Blob })
.catch(error => this.handleError(error))
.subscribe((response: Response) => {
this.pdfBlob = new Blob([response.blob()], { type: 'application/pdf' });
const blobUrl = URL.createObjectURL(this.pdfBlob);
const iframe = document.createElement('iframe');
iframe.style.display = 'none';
iframe.src = blobUrl;
document.body.appendChild(iframe);
iframe.contentWindow.print();
this.printingSub.next(false);
});
}
Startup.cs
public class Startup
{
public IConfiguration Configuration { get; }
public IConfigurationSection AppSettings { get; }
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile(@"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true)
.AddEnvironmentVariables();
Configuration = builder.Build();
AppSettings = Configuration.GetSection("appSettings");
}
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
ConfigureDatabase();
ConfigurePolicies(services);
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddOptions();
services.Configure<AppAccessSettings>(s =>
{
s.Env = AppSettings.GetSection("env").Value;
s.EnableAuth = bool.Parse(AppSettings.GetSection("enableAuth").Value);
});
services.AddMvc().AddJsonOptions(options =>
options.SerializerSettings.ContractResolver = new Newtonsoft.Json.Serialization.DefaultContractResolver()
);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
// Configure JWT authentication
Authentication.SetVarFromFile(AppSettings.GetSection("authFile").Value);
Authentication.SetAuth(ref app, AppSettings.GetSection("audience").Value);
app.UseCors("CorsPolicy");
app.UseMvc();
}
private void ConfigureDatabase()
{
string dbSource = AppSettings.GetSection("env").Value;
OracleEnv.Connection = Configuration.GetSection("connectionStrings").GetSection(dbSource).Value;
}
private void ConfigurePolicies(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy",
builder => builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials());
});
services.AddAuthorization(options =>
{
options.AddPolicy("EnableAuth",
policy => policy.Requirements.Add(new AuthRequirement(Configuration)));
});
services.AddSingleton<IAuthorizationHandler, UserAuthHandler>();
}
}
private void ConfigurePolicies(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy",
builder => builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials());
});
services.AddAuthorization(options =>
{
options.AddPolicy("EnableAuth",
policy => policy.Requirements.Add(new AuthRequirement(Configuration)));
});
services.AddSingleton<IAuthorizationHandler, UserAuthHandler>();
}
Pickup Sheet API 方法
[Route("PickupSheet")]
public IActionResult GetPickupSheet(string pickupId, bool barCode)
{
PbReportGenerator rpt = new PbReportGenerator();
byte[] report = rpt.RetrievePDFReport(232, new Dictionary<string, string>
{
{ pickupId, "string" },
{ (barCode ? 1 : 0).ToString(), "int" }
});
var stream = new MemoryStream(report);
var response = File(stream, "application/pdf", String.Format("Report232_{0}.pdf", pickupId));
return response;
}
【问题讨论】:
-
好吧,CORS 是服务器端的,所以你必须展示你是如何在那里配置它的。
-
能分享一下pickupsheet api方法吗
-
发布整个 startup.cs。我想 UseCors 被调用太晚了。
-
我已经发布了启动代码。这在开发服务器和本地(邮递员)上运行良好。这只是我遇到问题的生产服务器。
-
我的经验不足在这方面占了上风。事实证明,来自浏览器的错误具有误导性(真是令人惊讶)。我错过了报告的 pdf 版本在生产中导出到的文件夹。
标签: asp.net-core cors