【问题标题】:HTTP request from javascript using raw message including headers来自 javascript 的 HTTP 请求,使用包含标头的原始消息
【发布时间】:2011-05-30 02:24:28
【问题描述】:

我知道如何使用 jQuery 或 XMLHttpRequest 从 javascript 向我的 REST api 发出 HTTP 请求。我现在要做的是在不为标头值设置属性的情况下发出请求。 HTTP request message 包括:

  • 请求行,例如 GET /images/logo.png HTTP/1.1,它从服务器请求名为 /images/logo.png 的资源
  • 标题,例如 Accept-Language: en
  • 空行
  • 可选的消息正文

对我的 api 的请求应如下所示:

GET /myapi/myresource/1234 HTTP/1.1
Host: localhost:51127
Content-Type: application/x-www-form-urlencoded
Accept: application/json, text/csv
Authorization: Basic <base64 encoded credentials>

我想打开一个到 localhost:51127 的连接,发送上面的文本,然后得到响应。这在javascript中可能吗?

更新:我知道如何设置标题。一世 只是想以不同的方式来做。 有很多方法可以“构建”一个 请求包括标头并发送它。 我只想手动构建它。

【问题讨论】:

  • jQuery.get
  • jQuery.get 是我现在正在做的事情的快捷方式,它使用 jQuery.ajax。这为您指定了标头,可以使用属性和回调覆盖这些标头。我想使用上面的格式指定标题和内容。

标签: javascript jquery http rest http-headers


【解决方案1】:

您可以获取 HmlHttpRequest 对象的实例并使用 setRequestHeader。

jQuery 有一个 beforeSend 处理程序,您可以设置它来获取实际的 hxr 对象。

  $.ajax({
      beforeSend: function(xhr){
          xhr.setRequestHeader("name","value");
       }
  ...
  })

【讨论】:

  • 这就是我现在正在做的事情。我不想那样设置标题。我想发送一个格式正确的 http 请求,其中已经包含了标头。
【解决方案2】:

Javascript 不支持套接字。您只能使用 XMLHTTPRequest 包装器或可选的 that 包装器(例如 jQuery.ajax)来构建 HTTP 查询。这是出于各种充分的理由,主要是安全性。

【讨论】:

    【解决方案3】:

    来这里寻找同样的东西。我认为可以构建一些东西,它接受原始请求文本并将其解析为 xmlHttpRequest 对象,将标头等放在正确的属性中。如果这样的东西已经存在,请评论一个链接。基本上,如果 jQuery 有一个 BuildRequestFromRaw(text) 函数,那就太棒了。

    【讨论】:

      【解决方案4】:

      要建立在 lonesomeday 的答案之上,以下是实际操作方法。

      function rawRequest(txt,cb) {
        let x = new XMLHttpRequest(),
            lines = txt.split("\n"),
            methods = [
              "GET",
              "POST",
              "PATCH",
              "PUT",
              "DELETE",
              "HEAD",
              "OPTIONS"
            ],
            host, path, method, version, body = "", headers = {}
        lines.forEach((x, i) => {
          if(!x.includes(":")) {
            let ind;
            methods.forEach(m => {
              let tmpIndex = x.indexOf(m);
              
              if(tmpIndex > -1) {
                if(!method) {
                  ind = tmpIndex;
                  let words = x.split(" ");
                  method = x.substring(
                    tmpIndex,
                    tmpIndex + 
                    m.length
                  );
                  method = method && method.trim();
                  path = words.find((y, k) => 
                    y[0] === "/"
                  )
                  path = path && path.trim();
                  version = (
                    x
                    .replace(method, "")
                    .replace(path, "")
                  ).trim();
                }
                
              }
            });
          } else {
            let indexOfSemiColon = x.indexOf(":");
            if(
              indexOfSemiColon > 0 &&
              indexOfSemiColon < x.length - 1
            ) {
            
              let key = x.substring(
                0,
                indexOfSemiColon
              ).trim(),
                  value = x.substring(
                    indexOfSemiColon + 1
                  ).trim();
               headers[key] = value;
               if(key.toLowerCase() == "host") {
                host = value
               }
         	 }
          }
        });
        let inds = []
        txt.split(/\r?\n/).forEach((x,i)=>
          x === "" 
          && inds.push(i)
        )
        let afterTwoLineBreaksIndex;
        inds.forEach((x,i) => {
          if(
            i < inds.length - 2 &&
            inds[i] === "" &&
            inds[i + 1] === ""
          ) {
            afterTwoLineBreaksIndex = i + 1;
          }
        });
        if(afterTwoLineBreaksIndex) {
          body = txt.substring(
            afterTwoLineBreaksIndex
          )
        }
        x.onreadystatechange = () => {
          if(x.readyState == 4 && x.status == 200) {
            if(cb) cb(x.response);
          } 
        }
        if(host && path && method) {
          x.open(
            method, 
            "http://" //don't know how to differentiate between http & https, if some1 could help out would be greate
            + host 
            + path
          );
          
          for(let k in headers) {
            x.setRequestHeader(k, headers[k]);
          }
          
          x.send(body);
        }
        return {
          headers,
          body,
          method,
          host,
          path,
          version
        } //for testing just return all the values we found
      }
      
      console.log(
        rawRequest(`
          GET /search?q=test HTTP/2
          Host: www.bing.com
          User-Agent: curl/7.54.0
          Accept: */*`
        ),
        rawRequest(`
          GET /foo/bar HTTP/1.1
          Host: example.org
          User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; fr; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8
          Accept: */*
          Accept-Language: fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3
          Accept-Encoding: gzip,deflate
          Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
          Keep-Alive: 115
          Connection: keep-alive
          Content-Type: application/x-www-form-urlencoded
          X-Requested-With: XMLHttpRequest
          Referer: http://example.org/test
          Cookie: foo=bar; lorem=ipsum;
        `),
         rawRequest(`
            GET /myapi/myresource/1234 HTTP/1.1
            Host: localhost:51127
            Content-Type: application/x-www-form-urlencoded
            Accept: application/json, text/csv
            Authorization: Basic <base64 encoded credentials>
         `)
        
       )

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-02-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-11-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多