对预检请求的响应没有通过访问控制检查:'访问 - 的值

时间:2018-03-18 17:08:38

标签: javascript go xmlhttprequest http-headers

我使用Go创建了一个API。它在邮递员中工作正常,但在使用javascript时却没有。当我使用javascript发布请求时,我收到一条错误消息,指出Access-Control-Allow-Origin设置为null。

去API代码:

package main

import (
    "fmt"
    "encoding/json"
    "github.com/gorilla/mux"
    "log"
    "net/http"
)

type Calculate struct {
    Operand1  string   `json:"Operand1,omitempty"`
    Operand2 string   `json:"Operand2,omitempty"`
    Operator  string   `json:"Operator,omitempty"`
}

type Answer struct {
    Res string  `json:"Res,omitempty"`
}


func do_Calculation(w http.ResponseWriter, r *http.Request) {
    var cal Calculate
    var ans Answer
    fmt.Println("Request Reached")
    w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
    w.Header().Set("Content-Type", "application/json; charset=UTF-8")
    w.Header().Set("Access-Control-Allow-Origin", "*")
    w.WriteHeader(http.StatusOK)
    json.NewDecoder(r.Body).Decode(&cal)
    // my stuff
    // res := do_Operations(convertToFloat(cal.Operand1),convertToFloat(cal.Operand2),cal.Operator)
    // ans = Answer{Res: floattostrwithprec(res, 4)}
    json.NewEncoder(w).Encode(ans)
}



// main function to boot up everything
func main() {
    router := mux.NewRouter()
    router.HandleFunc("/calculate", do_Calculation).Methods("POST")
    fmt.Println("Server online at port :8000")
    log.Fatal(http.ListenAndServe(":8000", router))
}

javascript代码:

var data = JSON.stringify({
  "Operand1": "2.6",
  "Operand2": "2.4",
  "Operator": "+"
});

var xhr = new XMLHttpRequest();

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === 4) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "http://localhost:8000/calculate");
xhr.setRequestHeader("Content-Type", "application/json");
xhr.setRequestHeader("Cache-Control", "no-cache");
xhr.setRequestHeader("Access-Control-Allow-Origin", "*");
xhr.setRequestHeader("Access-Control-Allow-Methods", "POST");
xhr.withCredentials = true;
xhr.send(data);

错误:

  

无法加载http://127.0.0.1:8000/calculate:对预检的响应   请求没有通过访问控制检查:的值   '访问控制允许来源'响应中的标题不能是   通配符' *'当请求的凭据模式为' include'时。起源   '空'因此不允许访问。凭据模式   XMLHttpRequest发起的请求由   withCredentials属性。

2 个答案:

答案 0 :(得分:1)

预检请求是在实际GET / POST / PUT /等之前向服务器发出的请求。 OPTIONS类型检查是否允许交叉原点。您的服务器显然没有实现OPTIONS调用,因为它在您的javascript错误中显示:OPTIONS localhost:8000/calculate 405 (Method Not Allowed)

由于这是使用方法OPTIONS的额外请求,因此它永远不会到达do_Calculation处理程序。所以你无法解决问题。

您需要注意的是注册OPTIONS类型的全局处理程序/并在其中返回正确的标题信息。

如果您使用杜松子酒或大猩猩或其他路由器,他们可能有一种简单的方法来设置这样的处理程序。如果您不使用特殊路由器或想要手动执行此操作,请检查here OPTIONS调用所需的标头。

在Javascript中,我认为你不必设置任何特殊的标题,但我不会赌它。上次我实现这个时,我只实现了go服务器端。

我将它与杜松子酒一起使用,只需使用以下代码:

CORSHandler = cors.New(cors.Config{
    AllowAllOrigins:  true,
    AllowMethods:     []string{"GET", "POST", "PUT", "DELETE", "HEAD"},
    AllowHeaders:     []string{"Origin", "Content-Length", "Content-Type"},
    AllowCredentials: false,
    MaxAge:           12 * time.Hour,
})
router.Use(CORSHandler)

答案 1 :(得分:0)

每当您使用凭据设置xhr请求为true时。它是一个安全循环漏洞,允许使用通配符*对所有域进行跨源请求。请将http://localhost:8000/添加到Access-Control-Allow-Origin

var xhr = new XMLHttpRequest();

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === 4) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "http://localhost:8000/calculate");
xhr.setRequestHeader("Content-Type", "application/json");
xhr.setRequestHeader("Cache-Control", "no-cache");
xhr.setRequestHeader("Access-Control-Allow-Origin", "http://localhost:8000");
xhr.setRequestHeader("Access-Control-Allow-Methods", "POST");
xhr.withCredentials = true;
xhr.send(data);

同样在go lang代码的标题中允许http://localhost:8000

func do_Calculation(w http.ResponseWriter, r *http.Request) {
    var cal Calculate
    var ans Answer
    fmt.Println("Request Reached")
    w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
    w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
    w.Header().Set("Content-Type", "application/json; charset=UTF-8")
    w.Header().Set("Access-Control-Allow-Origin", "http://localhost:8000")
    w.WriteHeader(http.StatusOK)
    json.NewDecoder(r.Body).Decode(&cal)
    // my stuff
    // res := do_Operations(convertToFloat(cal.Operand1),convertToFloat(cal.Operand2),cal.Operator)
    // ans = Answer{Res: floattostrwithprec(res, 4)}
    json.NewEncoder(w).Encode(ans)
}