我已经创建了旅行服务器。它工作正常,我们可以通过Insomnia发出POST
请求,但是当我们在前端的axios发出POST
请求时,它会发送错误:
has been blocked by CORS policy: Response to preflight request doesn’t pass access control check: It does not have HTTP ok status.
我们在axios上的要求
let config = {
headers: {
"Content-Type": "application/json",
'Access-Control-Allow-Origin': '*',
}
}
let data = {
"id": 4
}
axios.post('http://196.121.147.69:9777/twirp/route.FRoute/GetLists', data, config)
.then((res) => {
console.log(res)
})
.catch((err) => {
console.log(err)
});
}
我的go文件:
func setupResponse(w *http.ResponseWriter, req *http.Request) {
(*w).Header().Set("Access-Control-Allow-Origin", "*")
(*w).Header().Set("Access-Control-Allow-Methods", "POST,GET,OPTIONS, PUT, DELETE")
(*w).Header().Set("Access-Control-Allow-Headers", "Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization")
}
func WithUserAgent(base http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
ua := r.Header.Get("Jwt")
ctx = context.WithValue(ctx, "jwt", ua)
r = r.WithContext(ctx)
setupResponse(&w, r)
base.ServeHTTP(w, r)
})
}
const (
host = "localhost"
port = 5432
user = "postgres"
password = "postgres"
dbname = "postgres"
)
func main() {
psqlInfo := fmt.Sprintf("host=%s port=%d user=%s "+
"password=%s dbname=%s sslmode=disable",
host, port, user, password, dbname)
server := &s.Server{psqlInfo}
twirpHandler := p.NewFinanceServiceServer(server, nil)
wrap := WithUserAgent(twirpHandler)
log.Fatalln(http.ListenAndServe(":9707", wrap))
}
就像我之前在Insomnia上所说的那样,它工作得很好,但是当我们发出axios POST
请求时,在浏览器的控制台上会显示以下内容:
已被CORS政策阻止:对预检请求的响应未通过访问控制检查:它没有HTTP正常状态。
答案 0 :(得分:7)
我相信这是最简单的例子:
header := w.Header()
header.Add("Access-Control-Allow-Origin", "*")
header.Add("Access-Control-Allow-Methods", "DELETE, POST, GET, OPTIONS")
header.Add("Access-Control-Allow-Headers", "Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With")
您还可以为Access-Control-Max-Age
添加标题,当然,您可以允许任何所需的标题和方法。
最后,您想响应初始请求:
if r.Method == "OPTIONS" {
w.WriteHeader(http.StatusOK)
return
}
当然,仅使用中间件可能会更容易。我认为我没有使用过它,但是强烈建议使用this one。
答案 1 :(得分:3)
Angular和Django Rest Framework。
我向DRF API发出发布请求时遇到了类似的错误。 碰巧我缺少的只是端点的斜线。
答案 2 :(得分:2)
此答案说明了幕后发生的事情,以及如何以任何语言解决此问题的基础。供参考,请参见the MDN docs on this topic。
您正在请求从一个域(例如domain-a.com)上运行的JavaScript到另一个域(domain-b.com)上运行的API的URL。当您这样做时,浏览器必须询问domain-b.com是否可以接受来自domain-a.com的请求。它通过HTTP OPTIONS
请求来完成。然后,在响应中,domain-b.com上的服务器必须(至少)提供以下HTTP标头,说“是的,没关系”:
HTTP/1.1 204 No Content // or 200 OK
Access-Control-Allow-Origin: https://domain-a.com // or * for allowing anybody
Access-Control-Allow-Methods: POST, GET, OPTIONS // What kind of methods are allowed
... // other headers
如果您使用的是Chrome浏览器,请按F12并转到“网络”标签,查看domain-b.com上服务器给出的响应。
因此,从@threeve的原始答案回到最低要求:
header := w.Header()
header.Add("Access-Control-Allow-Origin", "*")
if r.Method == "OPTIONS" {
w.WriteHeader(http.StatusOK)
return
}
这将使任何地方的任何人都可以访问此数据。出于其他原因,他包含的其他标头也是必需的,但是这些标头是满足CORS(跨源资源共享)要求的最低要求。
答案 3 :(得分:1)
CORS问题应在后端修复。 临时解决方法使用此选项。
转到C:\Program Files\Google\Chrome\Application
打开命令提示符
执行命令chrome.exe --disable-web-security --user-data-dir="c:/ChromeDevSession"
使用上述选项,您可以打开没有安全性的新chrome 。这种镀铬不会引发任何问题。
答案 4 :(得分:0)
Enable cross-origin requests in ASP.NET Web API单击以获取更多信息
在WebService应用中启用CORS。首先,添加CORS NuGet软件包。在Visual Studio中,从“工具”菜单中选择“ NuGet程序包管理器”,然后选择“程序包管理器控制台”。在“程序包管理器控制台”窗口中,键入以下命令:
Install-Package Microsoft.AspNet.WebApi.Cors
此命令将安装最新的软件包并更新所有依赖项,包括核心Web API库。使用-Version标志可定位特定版本。 CORS软件包需要Web API 2.0或更高版本。
打开文件App_Start / WebApiConfig.cs。将以下代码添加到WebApiConfig.Register方法:
using System.Web.Http;
namespace WebService
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// New code
config.EnableCors();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
}
接下来,将[EnableCors]属性添加到您的控制器/控制器方法中
using System.Net.Http;
using System.Web.Http;
using System.Web.Http.Cors;
namespace WebService.Controllers
{
[EnableCors(origins: "http://mywebclient.azurewebsites.net", headers: "*", methods: "*")]
public class TestController : ApiController
{
// Controller methods not shown...
}
}
答案 5 :(得分:0)
此处提供的解决方案是正确的。但是,用户错误也可能发生相同的错误,其中您的端点请求方法与发出请求时使用的方法匹配。
例如,当您将方法请求为POST时,服务器端点是用“ RequestMethod.PUT”定义的。
答案 6 :(得分:0)
对我唯一有效的方法是在IIS中创建一个新应用程序,将其映射到完全相同的物理路径,然后仅将身份验证更改为匿名。
答案 7 :(得分:0)
对于任何查看此内容但添加Access-Control-Allow-Origin
都没有结果的人,请尝试也添加Access-Control-Allow-Headers
。可以使某人免受头痛。