我正在尝试通过 Angular 17 应用程序发出 http 请求。每次浏览器响应时:
从原点访问“http://localhost:8082/login”处的 XMLHttpRequest “http://localhost:4200”已被 CORS 策略阻止:响应 预检请求未通过访问控制检查:它没有 HTTP 正常状态。
在我的角度拦截器中正在传递此标头:
@Injectable()
export class HttpInterceptor implements HttpInterceptor {
constructor(private router: Router,
private authService: AuthService) {
}
intercept(req: HttpRequest<any>, nextHandler: HttpHandler): Observable<HttpEvent<any>> {
const authToken = StorageUtil.getAuthToken();
let request = req.clone({
setHeaders: {
"Content-Type": "application/json",
'Access-Control-Allow-Origin': '*',
}
});
if (authToken == null || authToken == "") {
this.router.navigate(['/auth/login']).then(() => {
return throwError(() => new Error('Você precisa estar logado'));
});
}
if (authToken != null && StorageUtil.isTokenExpired()) {
this.authService.refreshToken().subscribe((resp) => {
const accestoken = resp.data.accessToken as string;
request = request.clone({
setHeaders: {
Authorization: `Bearer ${accestoken}`
}
});
return nextHandler.handle(request);
})
}
request = request.clone({
setHeaders: {
Authorization: `Bearer ${authToken}`
}
});
return nextHandler.handle(request);
}
}
我的 gorilla/mux Go API 将此中间件传递给服务器中的每个处理程序:
func jsonContentTypeMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
//Enable CORS
w.Header().Set("Content-Type", "application/json")
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS, PUT, DELETE")
w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With")
next.ServeHTTP(w, r)
})
}
func main(){
router := app.newRouter() //create my router with gorila/mux
startServer(jsonContentTypeMiddleware(router))
}
func startServer(handler http.Handler) {
fmt.Printf("API rodando na porta: %s", webPort)
s := &http.Server{
Addr: fmt.Sprintf("%s:%s", host, webPort),
Handler: handler,
WriteTimeout: time.Hour,
ReadTimeout: time.Hour,
}
log.Fatal(s.ListenAndServe())
}
我还需要使用 Http.OK Status 响应飞行前请求,所以基本上我更改了中间件功能,如下所示:
func jsonContentTypeMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
//Enable CORS
w.Header().Set("Content-Type", "application/json")
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS, PUT, DELETE")
w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With")
//this part here
if r.Method == http.MethodOptions {
w.WriteHeader(http.StatusOK)
return
}
// Call the next handler
next.ServeHTTP(w, r)
})
}
您已经意识到,手动实施 CORS 很容易出错。您最好依赖一些现有的 CORS 中间件库;您将在下面使用我自己的 CORS 库找到一种解决方案。
此外,随着 Go v1.22 添加了增强型路由模式,对像
gorilla/mux
这样的第三方路由器的需求已经没有意义了;您可以使用标准库的 net/http
包。
package main
import (
"io"
"log"
"net/http"
"github.com/jub0bs/cors"
)
func main() {
mux := http.NewServeMux()
mux.HandleFunc("GET /hello", handleHello)
corsMiddleware, err := cors.NewMiddleware(cors.Config{
Origins: []string{"*"},
Methods: []string{
http.MethodGet,
http.MethodPost,
http.MethodPut,
http.MethodDelete,
},
RequestHeaders: []string{
"Authorization",
"Content-Type",
"X-Requested-With",
},
})
if err != nil {
log.Fatal(err)
}
s := &http.Server{
Addr: "localhost:8080",
Handler: corsMiddleware.Wrap(mux),
// other settings omitted
}
log.Fatal(s.ListenAndServe())
}
func handleHello(w http.ResponseWriter, _ *http.Request) {
w.Header().Set("Content-Type", "application/json")
io.WriteString(w, `{"msg": "Hello, World!"}`)
}