【发布时间】:2018-07-24 05:26:37
【问题描述】:
我正在使用 .NET Core 2.0 和 Angular 4 在本地创建网页。我能够让我的前端成功提交 GET 请求,但不能提交 POST。我已经尝试了所有启用 CORS 和 Windows 身份验证的方法,但我总是收到未经授权的错误。我在这里错过了什么才能通过飞行前?我假设它与 Windows 身份验证有关,但我发现的所有内容都只是说我需要 'withCredentials:true' 标头选项。
角度服务
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json'
}),
withCredentials: true
};
@Injectable()
export class TestService {
constructor(private http: HttpClient) { }
private baseURL = 'http://localhost:58214/api/{insert_app_name_here}';
getAllRules() {
console.log('Getting rules');
return this.http.get<RuleItem>(this.baseURL).subscribe(res => {
console.log(res);
});
}
createNewRule(ri: RuleItem) {
return this.http.post<RuleItem>(this.baseURL, JSON.stringify(ri), httpOptions).subscribe(res => {
console.log(res);
}, err => {
console.log('Error occurred: ', err);
});
}
}
.NET CORE 2.0 控制器
// [EnableCors("SitePolicy")]
[Route("api/[controller]")]
public class TestController : Controller
{
private readonly RuleContext _context;
public TestController(RuleContext context)
{
_context = context;
}
[HttpGet]
public IEnumerable<RuleItem> GetAll()
{
return _context.RuleItems.ToList();
}
[HttpGet("{id}", Name = "GetRule")]
public IActionResult GetById(long id)
{
var item = _context.RuleItems.FirstOrDefault(r => r.Id == id);
if (item == null)
{
return NotFound();
}
return new ObjectResult(item);
}
[HttpPost]
public IActionResult Create(RuleItem item)
{
if (item == null)
{
return BadRequest();
}
_context.RuleItems.Add(item);
_context.SaveChanges();
return CreatedAtRoute("GetTodo", new { id = item.Id }, item);
}
}
Startup.cs
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
/*
services.AddCors(options =>
{
options.AddPolicy("SitePolicy", builder =>
{
builder.AllowAnyOrigin()
.AllowAnyOrigin()
.AllowAnyMethod()
.AllowCredentials();
});
});
services.AddAuthentication(IISDefaults.AuthenticationScheme);*/
services.AddMvc();
var connection = @"Server=servername;Database=dbname;Trusted_Connection=true;MultipleActiveResultSets=True;";
services.AddDbContext<RuleContext>(options => options.UseSqlServer(connection));
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
// app.UseCors("SitePolicy");
app.UseMvc();
}
}
web.config 如果我以编程方式添加了 CORS,不确定是否需要这个,但这是成功摆脱“没有允许来源标头存在”错误的唯一解决方案
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="http://localhost:4200" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
<add name="Access-Control-Allow-Methods" value="GET,POST,PUT,DELETE,OPTIONS" />
<add name="Access-Control-Allow-Credentials" value="true" />
</customHeaders>
</httpProtocol>
</system.webServer>
</configuration>
编辑 - 进行了以下更改:删除了 web.config 文件,添加了全局 CORS 规则。以下是更改:
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddCors();
//services.AddAuthentication(IISDefaults.AuthenticationScheme);
services.AddMvc();
var connection = @"Server=server;Database=db;Trusted_Connection=true;MultipleActiveResultSets=True;";
services.AddDbContext<RuleContext>(options => options.UseSqlServer(connection));
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseCors(builder =>
{
builder.AllowAnyOrigin()
.AllowAnyOrigin()
.AllowAnyMethod()
.AllowCredentials();
});
app.UseMvc();
}
}
控制器
[Route("api/[controller]")]
public class TestController : Controller
{
private readonly RuleContext _context;
public TestController(RuleContext context)
{
_context = context;
}
[HttpGet]
public IEnumerable<RuleItem> GetAll()
{
return _context.RuleItems.ToList();
}
[HttpGet("{id}", Name = "GetRule")]
public IActionResult GetById(long id)
{
var item = _context.RuleItems.FirstOrDefault(r => r.Id == id);
if (item == null)
{
return NotFound();
}
return new ObjectResult(item);
}
[HttpPost]
public IActionResult Create(RuleItem item)
{
if (item == null)
{
return BadRequest();
}
_context.RuleItems.Add(item);
_context.SaveChanges();
return CreatedAtRoute("GetTodo", new { id = item.Id }, item);
}
}
这是我现在收到的错误消息的图像:401 Error
【问题讨论】:
-
你不需要编辑你的 web.config(你也不需要提供一个,
dotnet publish会自动创建一个)。启用 CORS 只需将app.UseCors(builder => builder .AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin().AllowCredentials())添加到应用程序管道。 -
是的,这就是我最初的想法。我已经输入了确切的代码,但它不起作用。我收到“未指定允许来源标头”错误。我尝试使用 AllowAnyOrigin,然后将我的 localhost:4200 明确定义为唯一允许的来源
-
中间件已经处理好了。您可以通过设置
Origin标头来使用邮递员测试 CORS。您可能需要禁用邮递员中的设置,因为他可能会覆盖原点。基本上,如果您将原始标头设置为与您的 PC 主机名不同的内容,则应该触发中间件,并且它应该将 CORS 标头添加到响应中。 -
此外,如果您定义策略名称,您的控制器上应该有
[EnableCors("PolicyName")]属性。如果你像我告诉你的那样应用它,它没有策略名称,它应该全局应用于你的应用程序,没有任何属性。 -
你说得对,我想我没有适当地传递令牌。至少这是一次很好的学习经历。我将使用 NTLM 令牌并验证这是问题并将其关闭。非常感谢!
标签: c# angular asp.net-core asp.net-core-2.0