souldreamer / xhr2-cookies

XMLHttpRequest polyfill for node.js
2 stars 13 forks source link

xhr2-cookies couldn't run with react-native #7

Open jiangbo0216 opened 5 years ago

jiangbo0216 commented 5 years ago

I integrate web3.js with react-native,and web3.js use xhr2-cookies to initiate a network request. but it counldn't run ,do you have any fixes on it. https://github.com/ethereum/web3.js/issues/2054#issue-381838929

and I found in react-native ,use the buildt-in function XMLHttpRequest to replace require('xhr2-cookies').XMLHttpRequest and the code can do well. and my solution as follow:

node_modules\web3-providers-http\src\index.js

// var XHR2 = require('xhr2-cookies').XMLHttpRequest // jshint ignore: line

HttpProvider.prototype._prepareRequest = function(){
    // var request = new XHR2();
    var request = new XMLHttpRequest();
    // request.nodejsSet({
    //     httpsAgent:this.httpsAgent,
    //     httpAgent:this.httpAgent
    // });

    request.open('POST', this.host, true);
    request.setRequestHeader('Content-Type','application/json');
    request.timeout = this.timeout && this.timeout !== 1 ? this.timeout : 0;
    request.withCredentials = true;

    if(this.headers) {
        this.headers.forEach(function(header) {
            request.setRequestHeader(header.name, header.value);
        });
    }

    return request;
};
bikedawuwang commented 5 years ago

I met this problem too, but I came up with a solution.

Because location is empty in global 1.

    var defaultProtocol = global.location.protocol.search(/^https?:$/) === -1 ? 'http:' : ''

I found this in the compiled code, which led to my HTTP request not being sent because there was no location in the global, which led to my code catching directly.

So I came up with a temporary solution, which is to manually inject location or change the compiled code. Of course, the former is more flexible.

    config = {
        protocol: '' // 'https'
    }

    global.location = {
        protocol: config.protocol
    };

Before react-native initialization, inject location into global.

2.

    var defaultProtocol = null;
    if (global.location) {
        defaultProtocol = global.location.protocol.search(/^https?:$/) === -1 ? 'http:' : ''
    }
    else {
        defaultProtocol = 'http:'
    }

Or go directly to the compiled code to find the code and change it.

I hope this will help you. @jiangbo0216