我已经创建了旅行服务器。它工作正常,我们可以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.
Run Code Online (Sandbox Code Playgroud)
我们对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)
});
}
Run Code Online (Sandbox Code Playgroud)
我的文件:
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))
}
Run Code Online (Sandbox Code Playgroud)
就像我之前在Insomnia上所说的那样,它工作得很好,但是当我们发出axios POST请求时,在浏览器的控制台上会显示以下内容:
已被CORS政策阻止:对预检请求的响应未通过访问控制检查:它没有HTTP正常状态。
Rya*_*ton 23
这个答案解释了幕后发生的事情,以及如何用任何语言解决这个问题的基础知识。如需参考,请参阅有关此主题的 MDN 文档。
您正在从一个域(例如 domain-a.com)上运行的 JavaScript 向另一个域(domain-b.com)上运行的 API 发出对 URL 的请求。当你这样做时,浏览器必须询问 domain-b.com 是否允许来自 domain-a.com 的请求。它通过 HTTPOPTIONS请求来实现。然后,在响应中,域 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
Run Code Online (Sandbox Code Playgroud)
如果您使用的是 Chrome,则可以通过按 F12 并转到“网络”选项卡查看 domain-b.com 上的服务器提供的响应来查看响应。
所以,回到@threeve 的原始答案的最低限度:
header := w.Header()
header.Add("Access-Control-Allow-Origin", "*")
if r.Method == "OPTIONS" {
w.WriteHeader(http.StatusOK)
return
}
Run Code Online (Sandbox Code Playgroud)
这将允许任何地方的任何人访问这些数据。由于其他原因,他包含的其他标头是必需的,但这些标头是满足 CORS(跨源资源共享)要求的最低要求。
Eri*_* Fu 21
对于尚未找到解决方案的任何人,如果您正在使用:
该错误是因为浏览器正在向您的路由发送预检 OPTIONS 请求,而没有身份验证标头,因此无法获取 CORS 标头作为响应。
为了解决这个问题,我为没有身份验证的 OPTIONS 方法添加了另一条路线,并且 lambda 集成仅返回 { statusCode: 200 };
thr*_*eve 13
我相信这是最简单的例子:
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")
Run Code Online (Sandbox Code Playgroud)
您还可以为添加标题Access-Control-Max-Age,当然也可以允许任何所需的标题和方法。
最后,您想响应初始请求:
if r.Method == "OPTIONS" {
w.WriteHeader(http.StatusOK)
return
}
Run Code Online (Sandbox Code Playgroud)
编辑(2019年6月):我们现在为此使用大猩猩。他们的东西得到了更积极的维护,他们已经做了很长时间了。保留链接到旧链接,以防万一。
以下是旧的中间件建议: 当然,为此使用中间件可能会更容易。我不认为我已经用它,但是这一次似乎来得强烈推荐。
小智 9
在 ASP.NET Web API 中启用跨域请求点击了解更多信息
在 WebService 应用程序中启用 CORS。首先,添加 CORS NuGet 包。在 Visual Studio 中,从“工具”菜单中选择 NuGet 包管理器,然后选择包管理器控制台。在包管理器控制台窗口中,键入以下命令:
Install-Package Microsoft.AspNet.WebApi.Cors
Run Code Online (Sandbox Code Playgroud)
此命令安装最新的包并更新所有依赖项,包括核心 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 }
);
}
}
}
Run Code Online (Sandbox Code Playgroud)
接下来,将 [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...
}
}
Run Code Online (Sandbox Code Playgroud)
CORS 问题应该在后端修复。临时解决方法使用此选项。
去 C:\Program Files\Google\Chrome\Application
打开命令提示符
执行命令 chrome.exe --disable-web-security --user-data-dir="c:/ChromeDevSession"
使用上述选项,您可以在没有安全性的情况下打开新的 chrome。这个 chrome 不会引发任何 cors 问题。
| 归档时间: |
|
| 查看次数: |
94591 次 |
| 最近记录: |