Giter VIP home page Giter VIP logo

http-browserify's Introduction

http-browserify

The http module from node.js, but for browsers.

When you require('http') in browserify, this module will be loaded.

example

var http = require('http');

http.get({ path : '/beep' }, function (res) {
    var div = document.getElementById('result');
    div.innerHTML += 'GET /beep<br>';
    
    res.on('data', function (buf) {
        div.innerHTML += buf;
    });
    
    res.on('end', function () {
        div.innerHTML += '<br>__END__';
    });
});

http methods

var http = require('http');

var req = http.request(opts, cb)

where opts are:

  • opts.method='GET' - http method verb
  • opts.path - path string, example: '/foo/bar?baz=555'
  • opts.headers={} - as an object mapping key names to string or Array values
  • opts.host=window.location.host - http host
  • opts.port=window.location.port - http port
  • opts.responseType - response type to set on the underlying xhr object

The callback will be called with the response object.

var req = http.get(options, cb)

A shortcut for

options.method = 'GET';
var req = http.request(options, cb);
req.end();

request methods

req.setHeader(key, value)

Set an http header.

req.getHeader(key)

Get an http header.

req.removeHeader(key)

Remove an http header.

req.write(data)

Write some data to the request body.

If only 1 piece of data is written, data can be a FormData, Blob, or ArrayBuffer instance. Otherwise, data should be a string or a buffer.

req.end(data)

Close and send the request body, optionally with additional data to append.

response methods

res.getHeader(key)

Return an http header, if set. key is case-insensitive.

response attributes

  • res.statusCode, the numeric http response code
  • res.headers, an object with all lowercase keys

compatibility

This module has been tested and works with:

  • Internet Explorer 5.5, 6, 7, 8, 9
  • Firefox 3.5
  • Chrome 7.0
  • Opera 10.6
  • Safari 5.0

Multipart streaming responses are buffered in all versions of Internet Explorer and are somewhat buffered in Opera. In all the other browsers you get a nice unbuffered stream of "data" events when you send down a content-type of multipart/octet-stream or similar.

protip

You can do:

var bundle = browserify({
    require : { http : 'http-browserify' }
});

in order to map "http-browserify" over require('http') in your browserified source.

install

With npm do:

npm install http-browserify

license

MIT

http-browserify's People

Contributors

aredridel avatar brycebaril avatar coverslide avatar derekr avatar erithmetic avatar forbeslindesay avatar hendrikcech avatar max-mapper avatar relvao avatar shenanigans avatar tehshrike avatar tellnes avatar terinjokes avatar timbeyer avatar tschaub avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

http-browserify's Issues

Use asynchronous module definition

AsynchronousDefinition would allow to load the lib asynchronously in the browser:

    require('http', function(http) {
        // do stuff with http here
    });

http://requirejs.org/ and other asynchronous loaders support this.

In the library, this consists of wrapping all the code in a function that will be called by the loader when appropriate (after all dependencies are loaded, etc):

    define(['dependency1', 'dependency2', ...], function(dep1, dep2, ...) {
        var http;
        http.request = ...;

        return http;
    });

Support `res.setEncoding` and non-text response types

Response data in http-browserify seems to default to text. In node http it seems to default to buffer. Independent of defaults, the node version supports setEncoding so you can change the type of the response. The browserify version should do the same.

What does the protip mean?

You can do:

var bundle = browserify({
    require : { http : 'http-browserify' }
});

in order to map "http-browserify" over require('http') in your browserified source.

I am confused. Should not things just work after browserify my.js -o bundle.js? Where and when do I use this?

After using http to make a request to GitHub's /users/$username/repos API to list repo names, I was able to get my code working in the server, but it's failing on the browser.

[Error] XMLHttpRequest cannot load https://api.github.com/users/bucaran/repos. 
Cannot use wildcard in Access-Control-Allow-Origin when credentials flag is true.

file://http://

When I make this request

{
  host: "http://www.reddit.com/r/jokes/.json?limit=100?",
  path: "/",
  method: "GET",
  withCredentials: false // this is the important part
}

I get this error:

 XMLHttpRequest cannot load file://http://www.reddit.com/r/jokes/.json?limit=100/. Cross origin requests are only supported for protocol schemes: http, data, chrome-extension, https, chrome-extension-resource.

I have no idea why it's prepending "file://" to "http://", and it's totally fucking up my day...

Is there any cure for this?

Default protocol is inconsistent with Node's.

If not specified, http-browserify sets the protocol to window.location.protocol. This differs from the behavior of Node (see https://nodejs.org/api/http.html#http_http_request_options_callback ). I assume the reasoning was to make https requests if the current location is also https (but I could be wrong here).

Does it make sense to mimic Node's behavior exactly, and just default to http: ?

The issue I'm running into is when running a script locally in the browser, so the protocol is "file:". http-browserify then tries to make file:// requests, which obviously fail.

Silent failure if content-length is manually set in browserified http request

This took me a little while to track down today -- I browserified an api client that was setting content-length when POSTing. This resulted in the posts hitting the server, but complete silence in the browser client code. It turns out this line was my problem (request.js line 23):

            if (!self.isSafeRequestHeader(key)) return;

Now, of course, my server doesn't actually care if content-length isn't sent, so I just stopped setting that header. I'm mostly apathetic about browserified code sending it versus node code (now) not sending it, since it works either way. But...

Is there a better way to do this?

More importantly -- is this the right way to handle "unsafe" headers? With no error, warning, etc. it makes it difficult to debug.

callback function is not called as should

Server is a digest auth node.

HTTPDigest.prototype.request = function (data, options, callback) {
    var self = this;
    http.request(options, function (res) {
      self._handleResponse(data, options, res, callback);
    }).end();
  };

if I do this in node I receive a 401 with nonce in order than to make the second request (the real one)
when browserified the a popup for the credentials is poped and the the function is not called but only after you click ok or cancel button.

globalAgent not defined

Hi,
I am using browserify, and I am facing an issue with some modules (example node-couchdb) that require the http module.
The error is Cannot set property 'maxSockets' of undefined
After some debugging, it seems that globalAgent is not defined in the http-browserify module.
Do you have any hints regarding this issue? Do you think this can fixed on your side?
Thank you

String response bodies with the word ArrayBuffer in it gets destroyed

Hello.

Just ran into this issue and it had be really stumped for a while. Since the program I am working on runs both in the browser and in node, and the response bodies with JSON were the same, I could not for the life of me figure out why I got "unexpected end of input" when the URLs, responses and everything were the same. The reason was that if a string response holds the exact phrase "ArrayBuffer" that particular buffer will be converted into a Uint8Array (ref https://github.com/substack/http-browserify/blob/c0869e5f1d57eac1ce12305e226eadf82b052e07/lib/response.js#L107)

For a POC, I have put together this page: https://eiriksm.github.io/browserify-test (read the console and watch the network tab for what it was supposed to look like).

Now, I didn't come here just to complain, so I tried to make a solution to this in a PR coming in 2 seconds. I am not 100% sure how this is supposed to be used, but at least it worked when I was sending buffers from a http.createServer. But as I said, I am not 100% sure how it is supposed to work, so corrections are of course welcome. The actual line of code is based on the style that follows in the next function in the file the patch alters (isArray)

Upgrade `Base64` dependency

Is it possible to upgrade the dependency Base64 from the current ~0.2.0 to latest (1.1.0)?

I have verified that Base64 is really only used once in http-browserify code and changing versions wouldn't break anything even though the semver indicates otherwise.

The root cause of my problems is that Base64 v0.2.0 offers WTFPL which is not white listed in our org. So static code analysis tools flag it as a policy violation. Base64 v 1.1.0 , on the other hand allows Apache 2.0 which is white listed in our org.

If there is a way to install the latest version of Base64 and make http-browserify point to this latest version then that could work as well. Note that webpack aliasing won't work since we need to pass static code analysis scrutiny which probably works off package-lock.json

response events eventually stop.

I've been testing streaming JSON parsing and i ran in to this bug.

https://gist.github.com/mikeal/5471142

If you comment out the json parsing lines (those fail earlier than this bug surfaces due to a jsonstream bug, you can watch the length of all the chunks that get emitted.

In Firefox these events eventually stop and if you kill the server you'll get an exception when trying to read the last of the data.

In Chrome you'll eventually stop getting chunks with any data in them and it'll emit thousands of zero length chunks.

Response inherits from Stream instead of Stream.Readable (requiring request module browserify workaround)

On node.js, the HTTP response object (which is named IncomingMessage in node.js) inherits from Stream.Readable:

util.inherits(IncomingMessage, Stream.Readable);

but in http-browserify, it only inherits from Stream:

util.inherits(Response, Stream);

This means the full stream API is not available as it is in Node, including the .resume() method. I believe this is the reason for this hack in the request module:

  } else if (response.resume) {
    // response.resume should be defined, but check anyway before calling.
    // Workaround for browserify.
    response.resume()
  }

to improve compatibility would it be possible for http-browserify Response to inherit from Stream.Readable? (are there any other changes needed than changing the utils.inherits call?)

edit: Stream is old-style (pre-0.10); this amounts to converting http-browserify to Streams2

http browserify broken when sending a full node url object

var url = { 
    host: "localhost:8081",
    hostname: "localhost",
    href: "http://localhost:8081/api/foo?bar=baz",
    method: "GET",
    path: "/api/foo?bar=baz",
    pathname: "/api/foo",
    port: "8081",
    protocol: "http:",
    query: "bar=baz",
    search: "?bar=baz",
    slashes: true
  };
  var request = http.get(url, noop);
expected: "http://localhost:8081/api/foo?bar=baz"
actual:   "http://localhost:8081:8081/api/foo?bar=baz"

The url that is requested has the port in it 2 times. This is because of this line.
https://github.com/substack/http-browserify/blob/master/index.js#L7

I am finishing up a pull request to fix this where it will try host first, then hostname+port.

Please let me know if you have any input.

case insensitive headers

I understand HTTP header names are case-insensitive (RFC 2616). I'm currently interacting with an API that does not follow protocol, it works via node's https but not browserify's.

If you want complete compatibility with node, I'd say remove the case insensitivity. Otherwise, if you want to just follow the spec, I understand.

In the meantime, I've been able to get my API working, by modifying the browserify source code to remove the tolowercase for the headers

Don't `require('buffer')`

The buffer implementation is a lot of code and http-browserify does not really need it to work. It is only needed for auth parameter to bas64 encode it.

Could it be document that the auth parameter is not supported or changed to depend on a base64 library or? Eg. base64-js which buffer-browserify depends on.

How to catch ECONNREFUSED?

In Node.js, when using the request function of the http module, you can subscribe to the error events of the returned object, such as:

var http = require('http');

var req = http.request('aaa.bbb.ccc.ddd', function (res) {
  console.log(res.statusCode);
});

req.on('error', function (err) {
  console.log('###');
});

req.end();

When I run this with a non-existent IP on Node.js, everything is fine, and the result is ### printed to the console.

When I run this using http-browserify in Chrome, I get an uncaught exception. Am I doing something wrong?

http.request not handling relative paths

If window.location.href is http://localhost:8000/app/#/, one would expect a GET to ./ping to be a request to http://localhost:8000/app/ping. At least, that's how XMLHttpRequest behaves.

But instead it looks like http.request sends the request to http://localhost:8000./ping, which is not a valid URL...

Allow XMLHttpRequest to be mocked by test frameworks (e.g., jasmine-ajax; sinon)

Currently the local xhrHttp is defined at require-time.

Unfortunately, libraries for mocking out XMLHttpRequests that rely on replacing global.XMLHttpRequest with a mock do not play nicely with this - you've already gained a reference to the real XMLHttpRequest by the time they replace the global.XMLHttpRequest reference.

Will be submitting a pull request to fix.

Support for string as request parameter

[email protected] supports using a string as the request parameter. If it is one, it converts it into an object via url.parse.

http.request.get('http://github.com/');

// equivalent to
http.request.get({
  hostname: 'github.com'
});

https://github.com/joyent/node/blob/85e4fc4306055656f0acab0052ae6da73bfbeb1f/lib/http.js#L53-L55

I was wondering if the lack of support for this in http-browserify was intentional or not (it left me scratching my head for a bit until I saw the cause). If it was unintentional, I would be more than happy to make a PR for this.

Suggested Setup in README Doesn't Work

When I dial this into the latest browserify:

var bundle = browserify({
    require : { http : 'http-browserify' }
});

I get an error saying Error: path must be a string.

Please update with correct configuration instructions!

Response object does not have response.headers

The response object in Node's http module (an instance of http.IncomingMessage) exposes the response headers via response.headers (and not response.getHeader()). This module does the opposite - http-browserify's response object has response.getHeader() (and not response.headers).

The response object should be changed to match Node core's http module by adding .headers and removing .getHeader().

HEAD request not working on Edge

When doing a HEAD request with the http library, the javascript just crashes and does not give me any answers.

I tried debugging it myself and found that the library uses fetch to fetch the head. The response of this message is given to IncomingMessage. IncomingMessage assumes that a response has a body. In the case of Edge, the body is just null, because a HEAD request has no body.

Nonetheless, this is accessed in anyway:

var reader = response.body.getReader()
		function read () {
			reader.read().then(function (result) {
				if (self._destroyed)
					return
				if (result.done) {
					self.push(null)
					return
				}
				self.push(new Buffer(result.value))
				read()
			}).catch(function(err) {
				self.emit('error', err)
			})
		}

And libraries crashes, causing the HEAD request to hang indefinitely.

To be able to use my own code I added a monkey fix, to temporarily make edge work:

window.fetch_old = window.fetch
window.fetch = function () {
    var result = window.fetch_old.apply(null, arguments);
    result.then_old = result.then;
    result.then = function (callback) {
        return result.then_old(function(response) {
            if(response.body === null){
                var body = { "getReader" : function () {
                 return {
                     "read" : function (){
                         return {
                             "then" : function (callback){
                                 callback({"done":true});
                                 return {"catch" : function(){}};
                             }
                         }
                     }
                 }   
                }};
                //override body....
                var handler = {
                    get: function(target, name) {
                        if(name === "body"){
                            return body;
                        }
                        return target[name];
                    }
                };
                var response_new = new Proxy(response, handler);
                return callback(response_new);
            }
            return callback(response);
        });
    }
    return result;
};

But obviously, it would be great if this could be fixed in the library, instead of my ugly hack.

Setting XHR response type fails due to xhr.responseType being modified before XHR is opened

http-browserify accepts a 'responseType' parameter to set the XHR response type. However, in Firefox 31 at least, the logic to set the response type always fails because it is set before xhr.open() is called.

The call to set 'xhr.responseType = params.responseType' fails with 'An attempt was made to use an object that is not, or is no longer, usable' ala. http://stackoverflow.com/questions/13216903/get-binary-data-with-xmlhttprequest-in-a-firefox-extension

Support `FormData`

Posting FormData can be done using something like:

  var fd = new FormData()
  fd.append('image', file)
  var req = new XMLHttpRequest()
  req.onload = function () {
    callback(null, req.responseText)
  }
  req.onerror = callback
  req.open('post', 'https://api.imgur.com:443/3/image.json')
  req.setRequestHeader('Authorization', 'Client-ID ' + clientID)
  req.send(fd)

However, I can see know way of handling FormData using the built in http module.

(see browserify/browserify#439)

Needs Maintainer

@substack doesn't appear to have time to maintain this; perhaps you could put out a call for a maintainer? There are a large number of open PRs and issues, but no commits for a long time.

Node 0.8 required

I know I can upgrade.
But I recommend at least updating minor version.

Because now for example browserify requires 0.8 too.

"http-browserify" : "~0.1.1",

c5ffd1d#L2R13

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.