我使用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属性。
答案 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)
}