最近做一個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"} } }; }
結果:

