最近做一个React的简单项目,需要调用WebApi接口,调用遇到了CORS跨域问题,特此记录一下:
简单的js页面如下:
import React, { Component } from 'react';
class App extends Component{
render(){ return(
<ShoppingList name="Mark" />
);
}
};
var REQUEST_URL =
"https://localhost:44359/api/values";
class ShoppingList extends React.Component {
constructor(props){
super(props);
this.state={
error:null,
isLoaded:false,
items:[]
}
}
componentDidMount(){
fetch(REQUEST_URL, {
method: "GET", // *GET, POST, PUT, DELETE, etc.
mode: 'cors' // no-cors, cors, *same-origin
})
.then(res=>res.json())
.then(
(result)=>{
this.setState({
isLoaded:true,
items:result.items
});
},
(error)=>{
this.setState({
isLoaded:true,
error
})
}
)
}
render() {
const{error,isLoaded,items}=this.state;
if(error){
return<div>Error:{error.message}</div>
}else if(! isLoaded){
return <div>Loading...</div>;
}else {
return (
<ul>
{items.map(item => (
<li key={item.id}>
{item.id} {item.name}
</li>
))}
</ul>
);
}
}
}
export default App;
后端代码:
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
// GET api/values
[HttpGet]
public ActionResult<ItemsModel> Get()
{
return new ItemsModel
{
Items = new List<Item>
{
new Item{Id=1,Name="apple",Price = "5"},
new Item{Id=2,Name="banbana",Price = "3.5"}
}
};
}
调用的时候报错:Error:Failed to fetch
查看控制台报错:Failed to load https://localhost:44359/api/values: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. The response had HTTP status code 500. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
这是明显的跨域问题,一开始只是想着加个“Access-Control-Allow-Origin”的header给后台,就想着搜索如何添加这个头,结果方向是错的,搜到的结果都是不对(主要是版本陈旧)。后来想到这既然是跨域的问题,那就直接搜索.netcore 的WebApi如何支持跨域就好了(鄙视一下自己的记性,看过的东西都不知道深入理解一下,以至于用到的时候想不到走了好多弯路......),方向对了就很容易找到解决方案啦:
链接:https://docs.microsoft.com/zh-cn/aspnet/core/security/cors?view=aspnetcore-2.2
我选择的方案是:
使用属性启用 CORS
直接上代码(Startup文件中配置):
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddDefaultPolicy(
builder =>
{
builder.WithOrigins("*")
.AllowAnyHeader()
.AllowAnyMethod();
});
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
然后应用一下默认属性即可:
[EnableCors]
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
// GET api/values
[HttpGet]
public ActionResult<ItemsModel> Get()
{
return new ItemsModel
{
Items = new List<Item>
{
new Item{Id=1,Name="apple",Price = "5"},
new Item{Id=2,Name="banbana",Price = "3.5"}
}
};
}
结果:
来源:oschina
链接:https://my.oschina.net/u/4331344/blog/3542050