HTTP request from javascript using raw message including headers

前端 未结 4 662
说谎
说谎 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 
       `)
      
     )

提交回复
热议问题