来自 JavaScript 的 HTTP 请求使用包含标头的原始消息

发布于 2024-10-09 03:14:56 字数 831 浏览 0 评论 0原文

我知道如何使用 jQuery 或 XMLHttpRequest 从 javascript 向我的 REST api 发出 HTTP 请求。我现在想做的是发出请求而不设置标头值的属性。 HTTP 请求消息包括:

  • 请求行,例如 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 中可能吗?

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

I know how to make an HTTP request to my REST api from javascript using jQuery or XMLHttpRequest. What I want to do now is make the request without setting properties for the header values. An HTTP request message consists of:

  • Request line, such as GET /images/logo.png HTTP/1.1, which requests a resource called /images/logo.png from server
  • Headers, such as Accept-Language: en
  • An empty line
  • An optional message body

A request to my api should look something like this:

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>

I would like to open a connection to localhost:51127, send the above text, and get the response. Is this possible in javascript?

Update: I know how to set headers. I
just want to do it a different way.
There are lots of ways to "build" a
request including headers and send it.
I just want to build it manually.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

德意的啸 2024-10-16 03:14:56

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

There is no socket support in Javascript. You can only build HTTP queries by using the XMLHTTPRequest wrapper, or optionally wrappers for that such as jQuery.ajax. This is for all kinds of good reasons, principally security.

千里故人稀 2024-10-16 03:14:56

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

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

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

You can possibly get an instance of the HmlHttpRequest object and use the setRequestHeader.

jQuery has a beforeSend handler you can set to get the actual hxr object.

  $.ajax({
      beforeSend: function(xhr){
          xhr.setRequestHeader("name","value");
       }
  ...
  })
梦途 2024-10-16 03:14:56

为了以 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>
   `)
  
 )

To build on lonesomeday's answer, here's how to actually do it.

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>
   `)
  
 )

甜心小果奶 2024-10-16 03:14:56

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

Came here looking for same thing. I think it would be possible to build something which takes a raw request text and parses that to an xmlHttpRequest object putting the headers etc in the correct properties. Pls comment a link if something like this already exists. Basically if jQuery has a function to BuildRequestFromRaw(text) that would be awesome.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文