Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Show network requests such as fetch, WebSocket etc. in chrome dev tools #934

Closed
lelandrichardson opened this issue Apr 20, 2015 · 85 comments
Labels
Help Wanted :octocat: Issues ideal for external contributors. Ran Commands One of our bots successfully processed a command. Resolution: Locked This issue was locked by the bot.

Comments

@lelandrichardson
Copy link
Contributor

I've just taken a deep dive into React Native this past weekend, and (as suspected) I'm liking it a lot. Great job!

When I first started working with the fetch API to request resources, I had chrome dev-tools opened and I was really hoping that I would be able to inspect the web requests happening in chrome's "Network" tab. Of course, that is not the case :(

I am not sure what sort of hoops would have to be jumped through in order to make this a possibility, but I think it would be a great addition if it is possible. Adding this would bring the mobile development workflow even closer to the web development workflow, which RN has done such a good job of doing thus far. This is a huge pain-point for me in normal objective-c development as well, since there are not really any good free HTTP-debugging apps out there for mac OS, and even if there are, that would be yet-another-window to have open at all times.

@nicklockwood
Copy link
Contributor

This is an interesting. Idea. We polyfill the XMLHttpRequest API using native code when running in the JavaScriptCore executor, because XHR is a browser API and as such, simply doesn't exist in a pure-JS context.

But in theory, when running in a browser, we could offer the option to un-polyfill the API, and use the browser's HTTP request infrastructure instead. It would have to be an option that was separate from normal debug mode, because it wouldn't be a true test of the app behaviour (it would mask differences in the native XHR implementation), but it seems like a reasonable thing to want to do.

Another option would be to simply pipe request/response headers and bodies through to the JS console so they can be inspected. That would be simpler, but perhaps less useful?

Thoughts, @vjeux?

@vjeux
Copy link
Contributor

vjeux commented Apr 20, 2015

I had it un-polyfilled before but you run into CORS issues. If you correctly setup CORS then you can comment this line and see all the http requests in the chrome dev tools :)

GLOBAL.XMLHttpRequest = require('XMLHttpRequest');

@ide
Copy link
Contributor

ide commented Apr 20, 2015

For convenience it sounds like you can also turn off CORS (and maybe more - use at your own risk) by running Chrome with --disable-web-security. https://blog.nraboy.com/2014/08/bypass-cors-errors-testing-apis-locally/

@brentvatne
Copy link
Collaborator

@vjeux - very cool how easy that is to accomplish!

@lelandrichardson
Copy link
Contributor Author

@ide that's a nifty command line argument. Do you know if I would I be able to just launch chrome with that command line arg and then whenever I launch the debugger from RN it would just work? Or is there a place in the RN source code where I would want to add that command line argument? I will try and test out the former along with @vjeux 's changes myself when I get a chance.

@ide
Copy link
Contributor

ide commented Apr 21, 2015

I got this working in a crude way. First quit Chrome so none of its processes are running. I didn't find a way to apply the CLI switch to a single tab. Then run:

"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" --disable-web-security

note: a malicious site now can get your gmail, facebook, bank account, etc if you are logged in, so after you're done be sure to restart Chrome. also why I think it's better just to set up CORS if you own the endpoint or write a proxy.

Comment out the line in InitializeJavaScriptAppEngine.js mentioned above in this thread and then when you enable Chrome debugging in an app you get this:

screenshot 2015-04-21 14 10 19

It seems useful to track down issues like too many network requests or forgetting to gzip the responses but it won't help with debugging issues with Cocoa's networking stack that users are running. Also for more than basic HTTP requests (ex: NSURLSession) then advanced apps won't use the XMLHttpRequest polyfill. So, I think it's a good tool to have but Charles Proxy or getting PonyDebugger hooked up looks more fruitful in the longer term.

elliottsj added a commit to elliottsj/react-native that referenced this issue Aug 22, 2015
This allows users to inspect network requests in Chrome by commenting
the xhr polyfill in InitializeJavaScriptAppEngine.js:
  facebook#934 (comment)
elliottsj added a commit to elliottsj/react-native that referenced this issue Aug 22, 2015
This allows users to inspect network requests in Chrome by commenting
the xhr polyfill in InitializeJavaScriptAppEngine.js:
  facebook#934 (comment)
elliottsj added a commit to elliottsj/react-native that referenced this issue Aug 22, 2015
This allows users to inspect network requests in Chrome by commenting
the xhr polyfill in InitializeJavaScriptAppEngine.js:
  facebook#934 (comment)
elliottsj added a commit to elliottsj/react-native that referenced this issue Aug 22, 2015
packager.js to enable Chrome '--disable-web-security' flag.

This allows users to inspect network requests in Chrome by commenting
the xhr polyfill in InitializeJavaScriptAppEngine.js:
  facebook#934 (comment)

Usage:

    node packager.js --dangerouslyDisableChromeDebuggerWebSecurity

or:

    packager.sh --dangerouslyDisableChromeDebuggerWebSecurity
elliottsj added a commit to elliottsj/react-native that referenced this issue Aug 22, 2015
This allows...

1. launching Chrome on platforms other than OS X
2. users to launch their own instance of Chrome (e.g. via command line)
   rather than being forced to use the default instance (i.e.
   `tell application "Chrome"` always used the default instance)

`isDebuggerConnected()` addresses the problem in facebook#510 where the dev tools
would only open once per server session.

Add a '--dangerouslyDisableChromeDebuggerWebSecurity' flag to
packager.js to enable Chrome '--disable-web-security' flag.

This allows users to inspect network requests in Chrome by commenting
the xhr polyfill in InitializeJavaScriptAppEngine.js:
  facebook#934 (comment)

Usage:

    node packager.js --dangerouslyDisableChromeDebuggerWebSecurity

or:

    packager.sh --dangerouslyDisableChromeDebuggerWebSecurity
elliottsj added a commit to elliottsj/react-native that referenced this issue Aug 22, 2015
This allows...

1. launching Chrome on platforms other than OS X
2. users to launch their own instance of Chrome (e.g. via command line)
   rather than being forced to use the default instance (i.e.
   `tell application "Chrome"` always used the default instance)

`isDebuggerConnected()` addresses the problem in facebook#510 where the dev tools
would only open once per server session.

Add a '--dangerouslyDisableChromeDebuggerWebSecurity' flag to
packager.js to enable Chrome '--disable-web-security' flag.

This allows users to inspect network requests in Chrome by commenting
the xhr polyfill in InitializeJavaScriptAppEngine.js:
  facebook#934 (comment)

Usage:

    node packager.js --dangerouslyDisableChromeDebuggerWebSecurity

or:

    packager.sh --dangerouslyDisableChromeDebuggerWebSecurity
elliottsj added a commit to elliottsj/react-native that referenced this issue Aug 23, 2015
This allows...

1. launching Chrome on platforms other than OS X
2. users to launch their own instance of Chrome (e.g. via command line)
   rather than being forced to use the default instance (i.e.
   `tell application "Chrome"` always used the default instance)

`isDebuggerConnected()` addresses the problem in facebook#510 where the dev tools
would only open once per server session.

Add a '--dangerouslyDisableChromeDebuggerWebSecurity' flag to
packager.js to enable Chrome '--disable-web-security' flag.

This allows users to inspect network requests in Chrome by commenting
the xhr polyfill in InitializeJavaScriptAppEngine.js:
  facebook#934 (comment)

Usage:

    node packager.js --dangerouslyDisableChromeDebuggerWebSecurity

or:

    packager.sh --dangerouslyDisableChromeDebuggerWebSecurity
elliottsj added a commit to elliottsj/react-native that referenced this issue Aug 23, 2015
This allows...

1. launching Chrome on platforms other than OS X
2. users to launch their own instance of Chrome (e.g. via command line)
   rather than being forced to use the default instance (i.e.
   `tell application "Chrome"` always used the default instance)

`isDebuggerConnected()` addresses the problem in facebook#510 where the dev tools
would only open once per server session.

Add a '--dangerouslyDisableChromeDebuggerWebSecurity' flag to
packager.js to enable Chrome '--disable-web-security' flag.

This allows users to inspect network requests in Chrome by commenting
the xhr polyfill in InitializeJavaScriptAppEngine.js:
  facebook#934 (comment)

Usage:

    node packager.js --dangerouslyDisableChromeDebuggerWebSecurity

or:

    packager.sh --dangerouslyDisableChromeDebuggerWebSecurity
elliottsj added a commit to elliottsj/react-native that referenced this issue Aug 23, 2015
This allows...

1. launching Chrome on platforms other than OS X
2. users to launch their own instance of Chrome (e.g. via command line)
   rather than being forced to use the default instance (i.e.
   `tell application "Chrome"` always used the default instance)

`isDebuggerConnected()` addresses the problem in facebook#510 where the dev tools
would only open once per server session.

Add a '--dangerouslyDisableChromeDebuggerWebSecurity' flag to
packager.js to enable Chrome '--disable-web-security' flag.

This allows users to inspect network requests in Chrome by commenting
the xhr polyfill in InitializeJavaScriptAppEngine.js:
  facebook#934 (comment)

Usage:

    node packager.js --dangerouslyDisableChromeDebuggerWebSecurity

or:

    packager.sh --dangerouslyDisableChromeDebuggerWebSecurity
elliottsj added a commit to elliottsj/react-native that referenced this issue Aug 25, 2015
This allows...

1. launching Chrome on platforms other than OS X
2. users to launch their own instance of Chrome (e.g. via command line)
   rather than being forced to use the default instance (i.e.
   `tell application "Chrome"` always used the default instance)

`isDebuggerConnected()` addresses the problem in facebook#510 where the dev tools
would only open once per server session.

Add a '--dangerouslyDisableChromeDebuggerWebSecurity' flag to
packager.js to enable Chrome '--disable-web-security' flag.

This allows users to inspect network requests in Chrome by commenting
the xhr polyfill in InitializeJavaScriptAppEngine.js:
  facebook#934 (comment)

Usage:

    node packager.js --dangerouslyDisableChromeDebuggerWebSecurity

or:

    packager.sh --dangerouslyDisableChromeDebuggerWebSecurity
elliottsj added a commit to elliottsj/react-native that referenced this issue Aug 26, 2015
This allows...

1. launching Chrome on platforms other than OS X
2. users to launch their own instance of Chrome (e.g. via command line)
   rather than being forced to use the default instance (i.e.
   `tell application "Chrome"` always used the default instance)

`isDebuggerConnected()` addresses the problem in facebook#510 where the dev tools
would only open once per server session.

Add a '--dangerouslyDisableChromeDebuggerWebSecurity' flag to
packager.js to enable Chrome '--disable-web-security' flag.

This allows users to inspect network requests in Chrome by commenting
the xhr polyfill in InitializeJavaScriptAppEngine.js:
  facebook#934 (comment)

Usage:

    node packager.js --dangerouslyDisableChromeDebuggerWebSecurity

or:

    packager.sh --dangerouslyDisableChromeDebuggerWebSecurity
elliottsj added a commit to elliottsj/react-native that referenced this issue Sep 14, 2015
This allows...

1. launching Chrome on platforms other than OS X
2. users to launch their own instance of Chrome (e.g. via command line)
   rather than being forced to use the default instance (i.e.
   `tell application "Chrome"` always used the default instance)

`isDebuggerConnected()` addresses the problem in facebook#510 where the dev tools
would only open once per server session.

Add a '--dangerouslyDisableChromeDebuggerWebSecurity' flag to
packager.js to enable Chrome '--disable-web-security' flag.

This allows users to inspect network requests in Chrome by commenting
the xhr polyfill in InitializeJavaScriptAppEngine.js:
  facebook#934 (comment)

Usage:

    node packager.js --dangerouslyDisableChromeDebuggerWebSecurity

or:

    packager.sh --dangerouslyDisableChromeDebuggerWebSecurity
elliottsj added a commit to elliottsj/react-native that referenced this issue Sep 19, 2015
This allows...

1. launching Chrome on platforms other than OS X
2. users to launch their own instance of Chrome (e.g. via command line)
   rather than being forced to use the default instance (i.e.
   `tell application "Chrome"` always used the default instance)

`isDebuggerConnected()` addresses the problem in facebook#510 where the dev tools
would only open once per server session.

Add a '--dangerouslyDisableChromeDebuggerWebSecurity' flag to
packager.js to enable Chrome '--disable-web-security' flag.

This allows users to inspect network requests in Chrome by commenting
the xhr polyfill in InitializeJavaScriptAppEngine.js:
  facebook#934 (comment)

Usage:

    node packager.js --dangerouslyDisableChromeDebuggerWebSecurity

or:

    packager.sh --dangerouslyDisableChromeDebuggerWebSecurity
@kushal
Copy link
Contributor

kushal commented Sep 23, 2015

I wonder if the original implementation of XHR could be saved somewhere else in GLOBALS, e.g. GLOBALS.originalXhr = XMLHttpRequest ? Then it would be possible to undo the polyfill in application code rather than needing to patch and unpatch the RN libraries?

elliottsj added a commit to elliottsj/react-native that referenced this issue Sep 27, 2015
This allows...

1. launching Chrome on platforms other than OS X
2. users to launch their own instance of Chrome (e.g. via command line)
   rather than being forced to use the default instance (i.e.
   `tell application "Chrome"` always used the default instance)

`isDebuggerConnected()` addresses the problem in facebook#510 where the dev tools
would only open once per server session.

Add a '--dangerouslyDisableChromeDebuggerWebSecurity' flag to
packager.js to enable Chrome '--disable-web-security' flag.

This allows users to inspect network requests in Chrome by commenting
the xhr polyfill in InitializeJavaScriptAppEngine.js:
  facebook#934 (comment)

Usage:

    node packager.js --dangerouslyDisableChromeDebuggerWebSecurity

or:

    packager.sh --dangerouslyDisableChromeDebuggerWebSecurity
elliottsj added a commit to elliottsj/react-native that referenced this issue Sep 27, 2015
This allows...

1. launching Chrome on platforms other than OS X
2. users to launch their own instance of Chrome (e.g. via command line)
   rather than being forced to use the default instance (i.e.
   `tell application "Chrome"` always used the default instance)

`isDebuggerConnected()` addresses the problem in facebook#510 where the dev tools
would only open once per server session.

Add a '--dangerouslyDisableChromeDebuggerWebSecurity' flag to
packager.js to enable Chrome '--disable-web-security' flag.

This allows users to inspect network requests in Chrome by commenting
the xhr polyfill in InitializeJavaScriptAppEngine.js:
  facebook#934 (comment)

Usage:

    node packager.js --dangerouslyDisableChromeDebuggerWebSecurity

or:

    packager.sh --dangerouslyDisableChromeDebuggerWebSecurity
@JAStanton
Copy link
Contributor

Out of curiosity why was this issue closed? Seems like it's still a very useful to have feature. The workaround is pretty dangerous.

@vjeux vjeux reopened this Oct 5, 2015
@vjeux
Copy link
Contributor

vjeux commented Oct 5, 2015

You are right, this is a useful feature to have. Reopening it. @brentvatne is there a duplicate one somewhere?

@ide
Copy link
Contributor

ide commented Oct 5, 2015

Is there a good fix? Here are all the ideas I have:

  • Use Charles Proxy or something similar. I do this and find it works well since you can capture all traffic, and it works across all RN environments.
  • Don't use Chrome since people have important cookies saved there. Run in some kind of sandboxed Electron environment instead since you don't use Electron to log into your bank.
  • Run a proxy server and rewrite all URLs to go through it. Maybe can be done cleanly.

Kind of depends how far you want to go with the Chrome tools compared to investing in the JSC ones instead.

@kushal
Copy link
Contributor

kushal commented Oct 6, 2015

These issues only occur in the absence of CORS, right? Maybe it's possible
to detect CORS-compatible domains and route appropriately?

On Mon, Oct 5, 2015 at 4:53 PM James Ide [email protected] wrote:

Is there a good fix? Here are all the ideas I have:

  • Use Charles Proxy or something similar. I do this and find it works
    well since you can capture all traffic, and it works across all RN
    environments.
  • Don't use Chrome since people have important cookies saved there.
    Run in some kind of sandboxed Electron environment instead since you don't
    use Electron to log into your bank.
  • Run a proxy server and rewrite all URLs to go through it. Maybe can
    be done cleanly.

Kind of depends how far you want to go with the Chrome tools compared to
investing in the JSC ones instead.


Reply to this email directly or view it on GitHub
#934 (comment)
.

@ide
Copy link
Contributor

ide commented Oct 6, 2015

That's a good point... actually what if we just didn't solve the CORS issue? 1/ if you're talking to your own server, send back the right CORS header w/1-3 lines of code. 2/ if you're talking to someone else's server w/out the right CORS headers then you have lots of workarounds (proxy server, disable web security, Charles Proxy).

@chemitaxis
Copy link

Thanks for the solution ;)

@trazyn
Copy link

trazyn commented Mar 1, 2017

@brunolemos thanks guys

@SeanDunford
Copy link

Would definitely like to see this implemented. https://react-native.canny.io/feature-requests/p/show-network-activity-in-dev-tools

@seanadkinson
Copy link

I see the Network requests coming through using the proposed solution, but I don't see anything in Response or Preview tabs. Is anyone seeing the actual response payload in the Network tab? I tried on Chrome and Canary, same result for both.

@srhise
Copy link

srhise commented Apr 20, 2017 via email

@peterjacobson
Copy link

peterjacobson commented May 2, 2017

Using @brunolemos's
GLOBAL.XMLHttpRequest = GLOBAL.originalXMLHttpRequest || GLOBAL.XMLHttpRequest
in the index.ios.js as recommended by @tomaszpolanski:

I see the network requests in Chrome Dev Tools Network Tab,
BUT get the console error:

XMLHttpRequest cannot load https://<site>.com/api/users.  
Response to preflight request doesn't pass access control check: 
   No 'Access-Control-Allow-Origin' header is present on the requested resource. 
Origin 'http://localhost:8081' is therefore not allowed access. 
The response had HTTP status code 405.

Which breaks all requests (so breaks the app)
Any thoughts on how to add a header, or resolve this issue?

@Jacse
Copy link

Jacse commented May 10, 2017

@peterjacobson start a new instance of Chrome with flags --disable-web-security --user-data-dir. Makes sure you close all instances of Chrome first. E.g. on Windows: "C:\Program Files (x86)\Google\Chrome\Application\Chrome.exe" --disable-web-security --user-data-dir

@oliverbenns
Copy link

@brunolemos solution works well. But doesn't gives response bodies for some reason.

@srhise
Copy link

srhise commented May 25, 2017 via email

@beeant
Copy link

beeant commented Jun 10, 2017

@brunolemos same here

@nsisodiya
Copy link

Cannot believe, this is 2017, and we do not have a solution to this.

@brunolemos
Copy link
Contributor

brunolemos commented Jun 10, 2017

@srhise @beeant @nsisodiya If this doesn't show the body to you use this as a complement

@nsisodiya
Copy link

nsisodiya commented Jun 11, 2017 via email

@brunolemos
Copy link
Contributor

@nsisodiya if that's a need to you, maybe you can dive in to the react native source code and help with a pull request

@nsisodiya
Copy link

nsisodiya commented Jun 11, 2017 via email

@beeant
Copy link

beeant commented Jun 11, 2017

@brunobar79 I've been using that other way but it slows down the app when debugging because of console.log

@mschipperheyn
Copy link

@peterjacobson

GLOBAL.XMLHttpRequest = GLOBAL.originalXMLHttpRequest || GLOBAL.XMLHttpRequest

I don't get the headers passed through that way

@ospfranco
Copy link
Contributor

None of the proposed solutions is working for me, quite amazed that react-native doesn’t have a way to do something as simple as this.

@pavanmehta91
Copy link

@brunolemos Your solution does work. But there's one issue when doing multi-part file XHR requests. They fail when we use GLOBAL.XMLHttpRequest = GLOBAL.originalXMLHttpRequest || GLOBAL.XMLHttpRequest

@lattice0
Copy link

Not working with me. I can see the requests on chrome network monitor but they fail and then an error appears on the phone

@kashishgrover
Copy link

kashishgrover commented Jun 28, 2018

Seems like there isn't a proper solution so far. Meanwhile, I made @brunolemos's solution just a little bit prettier. My logs are flooded anyway, and I need something like this. Don't mind me. :)

const showApiCalls = () => {
  const baseUrl = 'http://www.mocky.io/';
  global._fetch = fetch;
  global.fetch = async (uri, options, ...args) => {
    const response = await global._fetch(uri, options, ...args);
    if (uri.includes(baseUrl)) {
      console.log(
        '🔵 API Call: ',
        uri,
        { request: { uri }, response },
      );
    }
    return response;
  };
};

@pencilcheck
Copy link

Adding GLOBAL.XMLHttpRequest = GLOBAL.originalXMLHttpRequest || GLOBAL.XMLHttpRequest; works but also introduces other issues which is more severe.

Now network requests will not work at all when react native debugger is turned on with this line in place.

Using react-native 0.47 on macOS

@kashishgrover
Copy link

kashishgrover commented Jul 9, 2018

screen shot 2018-07-09 at 3 06 25 pm

I didn't realise until a few days back how well network calls work in React Native Debugger. You just have to enable them by selecting Enable Network Inspect in the options. Try this. I absolutely love React Native Debugger. ❤️

@facebook facebook locked as resolved and limited conversation to collaborators Jul 22, 2018
@react-native-bot react-native-bot added the Resolution: Locked This issue was locked by the bot. label Jul 22, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Help Wanted :octocat: Issues ideal for external contributors. Ran Commands One of our bots successfully processed a command. Resolution: Locked This issue was locked by the bot.
Projects
None yet
Development

No branches or pull requests