doudang8824
doudang8824
2019-06-07 16:48

Angular&Golang“不存在允许访问的控制…”

已采纳

I am using Angular to build a front-end GUI app to interact with my API server written in Go.

I've tried adding the header on both ends, client and the server, yet no luck. I've tried disabling the http interceptor, so it doesn't add the JWT token in which case I get the unauthorized access error, which is expected. But wherever I add the token to the request (either with the interceptor or manually before making the get request) the unauthorized access error is gone (so far so good), but then the missing header error appears. The server should return JSON data of stored articles, and it works with Postman and my other vanilla JS front-end.

Go code:

r.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
  http.ServeFile(w, r, "./index.html")
})

allowedHeaders := handlers.AllowedHeaders([]string{"X-Requested-With"})
allowedOrigins := handlers.AllowedOrigins([]string{"*"})
allowedMethods := handlers.AllowedMethods([]string{"GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS"})

r.HandleFunc("/login", GetTokenHandler).Methods("POST")

apiRouter := r.PathPrefix("/api").Subrouter()
apiRouter.Use(jwtMiddleware.Handler)
apiRouter.HandleFunc("/articles", getArticles).Methods("GET")
apiRouter.HandleFunc("/articles/{id}", getArticle).Methods("GET")
apiRouter.HandleFunc("/articles", createArticle).Methods("POST")
apiRouter.HandleFunc("/articles/{id}", updateArticle).Methods("PUT")
apiRouter.HandleFunc("/articles/{id}", deleteArticle).Methods("DELETE")
fmt.Println("Server running on port", port)
log.Fatal(http.ListenAndServe(port, handlers.CORS(allowedHeaders, allowedOrigins, allowedMethods)(r)))

Angular get request:

this.http.get('http://localhost:8000/api/articles')
.subscribe(res => {
    console.log(res);
},
err => console.log(err));

Angular HttpInterceptor:

export class AuthInterceptor implements HttpInterceptor {

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

        const token = localStorage.getItem("token");

        if (token) {
            const cloned = req.clone({
                headers: req.headers.append("Authorization", "Bearer " + token)
            });

            return next.handle(cloned);
        }
        else {
            return next.handle(req);
        }
    }
}

I am getting this error:

... request.. has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

Edit: Go imports:

import (
    "encoding/json"
    "fmt"
    "log"
    "net/http"
    "strconv"
    "strings"
    "time"

    jwtmiddleware "github.com/auth0/go-jwt-middleware"
    "github.com/dgrijalva/jwt-go"
    "github.com/gorilla/handlers"
    "github.com/gorilla/mux"
)
  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

2条回答

  • dou44364983 dou44364983 2年前

    This issue is known as CORS. Cross Origin Resource Sharing. This is arises when the origin of the request and response is different. For example: If your project is on https://139.43.33.122:1111/ and your server is hosted on https://123.0.3.444:3000, then the origin of your request and response are completely different and thus, browser will block the response. This is the browser thing. Postman doesn't care about their origin. To receive response, there are 2 ways (maybe more but i use these 2 only).

    1. Additional Headers: If yoou have access/permission to server code, then add an additional header to the server responses: Access-Control-Allow-Origin: http://siteA.com, Access-Control-Allow-Methods: GET, POST, PUT, Access-Control-Allow-Headers: Content-Type.

    2. Use Extensions: There are multiple extensions that can bypass this restriction. IF you do not have access or permission to change the server response, then this is the way to go.I'm personally using this method only.

    点赞 评论 复制链接分享
  • douzhi0107 douzhi0107 2年前

    Following things will help you resolve this issue:

    1) Since you are including Authorization as well in the request header, allow the same in the server which seems to be missed.

    2) You can use Proxy.config to map to the desired host ( hostname + port) a) Create proxy.config.json file :

    {
      "/api/articles": {
        "target": "http://localhost:8000",
        "secure": false
      }
    }
    

    b) run via following command :

    ng serve --proxy-config proxy.conf.json
    

    Refer This To Setup Proxy

    try these things first.

    点赞 评论 复制链接分享