Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用JavaScript调用Go服务器?_Javascript_Http_Xmlhttprequest - Fatal编程技术网

如何使用JavaScript调用Go服务器?

如何使用JavaScript调用Go服务器?,javascript,http,xmlhttprequest,Javascript,Http,Xmlhttprequest,我正在使用Go、JavaScript和PostgreSQL开发一个web应用程序 我没有任何问题,以链接我的围棋程序与数据库。但是我对JavaScript有一些问题 这是我的Go代码,当我调用localhost:8080时,它连接到我的DB并返回我表中的一个随机元素: type Quote struct { ID int Phrase string Author string } var db *sql.DB func init() { var e

我正在使用Go、JavaScript和PostgreSQL开发一个web应用程序

我没有任何问题,以链接我的围棋程序与数据库。但是我对JavaScript有一些问题

这是我的Go代码,当我调用
localhost:8080
时,它连接到我的DB并返回我表中的一个随机元素:

type Quote struct {
    ID     int
    Phrase string
    Author string
}

var db *sql.DB



func init() {
    var err error
    db, err = sql.Open("postgres", "postgres://gauthier:password@localhost/quotes?sslmode=disable")
    if err != nil {
        panic(err)
    }

    if err = db.Ping(); err != nil {
        panic(err)
    }
    fmt.Println("You connected to your database")
}

func getQuotes(w http.ResponseWriter, r *http.Request) {
    if r.Method != "GET" {
        http.Error(w, http.StatusText(405), http.StatusMethodNotAllowed)
        return
    }
    rows, err := db.Query("SELECT id, phrase, author FROM citations ORDER BY RANDOM() LIMIT 1;")
    if err != nil {
        http.Error(w, http.StatusText(500), 500)
        return
    }
    defer rows.Close()
    quotations := make([]Quote, 0)
    for rows.Next() {
        qt := Quote{}
        err := rows.Scan(&qt.ID, &qt.Phrase, &qt.Author)
        if err != nil {
            panic(err)
        }
        quotations = append(quotations, qt)
    }
    if err = rows.Err(); err != nil {
        panic(err)
    }

    for _, qt := range quotations {
        payload, _ := json.Marshal(qt)
        w.Header().Add("Content-Type", "application/json")
        w.Write(payload)
    }
}

func main() {
    http.HandleFunc("/", getQuotes)
    http.ListenAndServe(":8080", nil)
}
当我运行这个程序并使用
curl-I localhost:8080
时,它会返回我所期望的,来自数据库的随机引用

`gauthier@gauthier-Latitude-7280:~/gocode/sprint0$ curl -i localhost:8080
 HTTP/1.1 200 OK
 Content-Type: application/json
 Date: Thu, 30 Aug 2018 12:28:00 GMT
 Content-Length: 116

 {"ID":7,"Phrase":"I've never had a problem with drugs. I've had problems with the police","Author":"Keith Richards"}`
现在,当我尝试发出相同的请求时,使用JavaScript而不是使用curl和那个小脚本:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>Random quote</title>
  </head>
  <body>
    <script type="text/javascript" language="javascript">
      function getQuotations() {
         httpRequest= new XMLHttpRequest();
         httpRequest.onreadystatechange = function() {
             alertContents(httpRequest)
         };
         httpRequest.open("GET", "http://localhost:8080", true);
      }

      function alertContents(httpRequest) {
          console.log("http status: "+httpRequest.status);
          console.log("http response: "+httpRequest.responseText);
      }
    </script>
    <button onclick="getQuotations()">Click here for a quotation</button>
  </body>
</html>

有人能帮我吗?

尝试以稍微不同的方式使用XMLHttpRequest,以便使用load事件:

 httpRequest= new XMLHttpRequest();
  httpRequest.load= function() {
             alertContents(this.responseText)
  };
  httpRequest.open("GET", "http://localhost:8080", true);
  httpRequest.send();

我觉得如果你对承诺感到满意的话,可以使用
fetch
简化这个过程。您不必处理
readystatechange
status
代码等。下面是一个示例

function getQuotations() {
  return fetch('http://localhost:8080')
    .then(response => response.json())
    .then(alertContents)
    .catch(console.error);
}

function alertContents(contents) {
  console.log(contents);
  alert(`"${contents.Phrase}" ~${contents.Author}`);
}

onreadystatechange
在“就绪状态”发生更改时触发,而不一定只是在请求完成时触发。
onreadystatechange
的MDN文档包含了一个如何正确使用它的好例子(即检查
readyState==4
):查看Chromium开发工具的网络窗格中的请求(单击它)——是否返回了任何内容?查看Chromium开发工具中的网络选项卡,查看是否有任何错误;您可能会遇到关于“访问控制允许原点”的错误。有关更多信息,请参阅和。我用您的代码替换我的代码,它返回我加载失败的
http://localhost:8080/: 请求的资源上不存在“Access Control Allow Origin”标头。因此,不允许访问源站“null”。
Javascript阻止您查看/加载来自应用程序本身以外的源站的内容-因此,如果您让goApp在localhost:8080为您的页面提供服务,是的,但我的Go应用程序和我的视图不在同一台机器上,我不知道Go如何为同一网络上但不在同一台机器上的文件提供服务
function getQuotations() {
  return fetch('http://localhost:8080')
    .then(response => response.json())
    .then(alertContents)
    .catch(console.error);
}

function alertContents(contents) {
  console.log(contents);
  alert(`"${contents.Phrase}" ~${contents.Author}`);
}