为了账号安全,请及时绑定邮箱和手机立即绑定

已被 CORS 策略阻止:对预检请求的响应未通过访问控制检查

已被 CORS 策略阻止:对预检请求的响应未通过访问控制检查

Go
慕的地8271018 2023-05-08 16:09:02
我已经创建了旅行服务器。它工作正常,我们可以POST通过 Insomnia 发出请求,但是当我们POST在前端通过 axios 发出请求时,它会发送错误: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)   });} 我的去文件: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 上所说的那样,它工作得很好,但是当我们发出 axiosPOST请求时,在浏览器的控制台上会出现以下内容:已被 CORS 策略阻止:对预检请求的响应未通过访问控制检查:它没有 HTTP 正常状态。
查看完整描述

7 回答

?
萧十郎

TA贡献1815条经验 获得超12个赞

我相信这是最简单的例子:


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, Authorization, X-Requested-With")

您还可以添加标题Access-Control-Max-Age,当然您可以允许任何您想要的标题和方法。


最后你想回应最初的请求:


if r.Method == "OPTIONS" {

    w.WriteHeader(http.StatusOK)

    return

}

编辑(2019 年 6 月):我们现在为此使用大猩猩。他们的东西得到了更积极的维护,而且他们已经这样做了很长时间。留下旧的链接,以防万一。


下面的旧中间件推荐: 当然,为此使用中间件可能会更容易。我不认为我已经使用过它,但是这个似乎是强烈推荐的。


查看完整回答
反对 回复 2023-05-08
?
慕标琳琳

TA贡献1830条经验 获得超9个赞

这个答案解释了幕后发生的事情,以及如何用任何语言解决这个问题的基础知识。有关参考,请参阅有关此主题的 MDN 文档。


您正在从一个域(比如 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(跨源资源共享)要求的最低要求。


查看完整回答
反对 回复 2023-05-08
?
元芳怎么了

TA贡献1798条经验 获得超7个赞

CORS 问题应该在后端修复。临时解决方法使用此选项。

  1. 打开命令提示符

  2. 导航到 chrome 安装位置输入cd "c:\Program Files (x86)\Google\Chrome\Application" OR cd "c:\Program Files\Google\Chrome\Application"

  3. 执行命令chrome.exe --disable-web-security --user-data-dir="c:/ChromeDevSession"

使用上述选项,您可以在没有安全保护的情况下打开新的 chrome。这个 chrome 不会抛出任何 cors 问题。

//img1.sycdn.imooc.com//6458ae500001790a13200238.jpg

查看完整回答
反对 回复 2023-05-08
?
Qyouu

TA贡献1786条经验 获得超11个赞

对于尚未找到解决方案的任何人,如果您正在使用:

  1. AWS HTTP API 网关;

  2. 您正在使用带有身份验证的任何方法进行路由和 lambda 集成;

  3. 您认为您已经正确配置了 CORS;

该错误是因为浏览器正在向您的路由发送预检 OPTIONS 请求而没有 Authentication 标头,因此无法获得 CORS 标头作为响应。

为了解决这个问题,我在没有身份验证的情况下为 OPTIONS 方法添加了另一条路线,并且 lambda 集成仅返回 { statusCode: 200 };


查看完整回答
反对 回复 2023-05-08
?
弑天下

TA贡献1818条经验 获得超8个赞

在 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...

    }

}


查看完整回答
反对 回复 2023-05-08
?
慕虎7371278

TA贡献1802条经验 获得超4个赞

Angular 和 Django Rest 框架。

我在向我的 DRF api 发出发布请求时遇到了类似的错误。碰巧我所缺少的只是端点的尾部斜杠


查看完整回答
反对 回复 2023-05-08
?
守着一只汪

TA贡献1872条经验 获得超3个赞

这里提供的解决方案是正确的。但是,同样的错误也可能发生在用户错误中,即您的端点请求方法与您在发出请求时使用的方法不匹配。

例如,当您将方法请求为 POST 时,服务器端点使用“RequestMethod.PUT”定义。


查看完整回答
反对 回复 2023-05-08
  • 7 回答
  • 0 关注
  • 1776 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信