HTTP request from javascript using raw message including headers

前端 未结 4 661
说谎
说谎 2021-01-21 15:25

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 he

相关标签:
4条回答
  • 2021-01-21 15:47

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

    0 讨论(0)
  • 2021-01-21 15:48

    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");
           }
      ...
      })
    
    0 讨论(0)
  • 2021-01-21 16:01

    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.

    0 讨论(0)
  • 2021-01-21 16:02

    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.

    0 讨论(0)
提交回复
热议问题