已被CORS政策屏蔽:对预检请求的响应未通过访问控制检查

时间:2018-11-14 10:52:31

标签: go axios

我已经创建了旅行服务器。它工作正常,我们可以通过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正常状态。

8 个答案:

答案 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问题应在后端修复。 临时解决方法使用此选项。

  1. 转到C:\Program Files\Google\Chrome\Application

  2. 打开命令提示符

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

使用上述选项,您可以打开没有安全性的新chrome 。这种镀铬不会引发任何问题。

enter image description here

答案 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...
    }
}

Enable Cross-Origin Requests (CORS) in ASP.NET Core

答案 5 :(得分:0)

此处提供的解决方案是正确的。但是,用户错误也可能发生相同的错误,其中您的端点请求方法与发出请求时使用的方法匹配。

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

答案 6 :(得分:0)

对我唯一有效的方法是在IIS中创建一个新应用程序,将其映射到完全相同的物理路径,然后仅将身份验证更改为匿名。

答案 7 :(得分:0)

对于任何查看此内容但添加Access-Control-Allow-Origin都没有结果的人,请尝试也添加Access-Control-Allow-Headers。可以使某人免受头痛。