hiddentao / gulp-server-livereload

Gulp plugin to run a local webserver with livereload enabled via socket.io. Also comes with standalone command-line interface.
MIT License
93 stars 28 forks source link

Browser not reloading #15

Closed tlkiong closed 8 years ago

tlkiong commented 9 years ago

I tried this. Everything is fine except for one minor issue - browser not reloading.

I installed this through npm. My app is a cordova app. I can launch the browser on the index.html But once I change a file and save, the browser does not reload (I am using Google Chrome) but on console, it is logged saying that they detect a file change. My gulp task is:

gulp.task('webserver', function() {
  gulp.src('www')
    .pipe(server({
      livereload: true,
      directoryListing: false,
      open: true,
      defaultFile: './index.html'
    }));
});

Error received on Chrome's console:

Refused to execute inline script because it violates the following Content Security Policy directive: "default-src 'self' data: gap: content: https://ssl.gstatic.com 'unsafe-eval'". Either the 'unsafe-inline' keyword, a hash ('sha256-MRj7teD3Lkdf-iLed_8_f4BgaMZi9YYlXhgQR2180fY='), or a nonce ('nonce-...') is required to enable inline execution. Note also that 'script-src' was not explicitly set, so 'default-src' is used as a fallback.

hiddentao commented 9 years ago

Quick Google showed me http://stackoverflow.com/questions/16625560/how-to-set-script-src-in-a-chrome-packaged-app. Are you working on a Chrome packaged app? I haven't used the livereload mechanism with that type of app before so am I'm not familiar with this error.

tlkiong commented 9 years ago

Now, this is weird. Since I am using AngularJS. Thanks for the heads up. Will check it out later. :)

sp90 commented 9 years ago

Got this same issue :+1: for a fix

born2net commented 8 years ago

same issue here

hiddentao commented 8 years ago

Need more info - what do you see in the JS console with the latest version?

kentr commented 8 years ago

Chrome 51.0.2704.103 (Mac) also fails to reload on file changes for me.

It works as-expected 2 or 3 times, then stops reloading. Safari appears to work continuously as-expected.

Not a packaged app -- just a simple standard web project.

I don't see any errors in the console. Terminal output shows no errors and a message that the file was changed:

[10:55:05] Livereload: file changed: /.../index.html
kentr commented 8 years ago

Just noticed this difference between Safari and Chrome:

In Safari, the livereload.js log messages appear every time the page auto-reloads:

[Log] LIVERELOAD: server at http://localhost:35729 (livereload.js, line 11)
[Log] LIVERELOAD: load script socket.io.js (livereload.js, line 11)
[Log] LIVERELOAD: connecting to server (livereload.js, line 11)
[Log] LIVERELOAD: successfully connected (livereload.js, line 11)

In Chrome, these log messages only appear on the first page load and on manual browser refreshes.

hiddentao commented 8 years ago

@kentr So you're saying that when the browser auto-refreshes after a livereload trigger the log messages don't appear? If so, does the livereload js script atleast get loaded by the browser in those cases?

kentr commented 8 years ago

@hiddentao

So you're saying that when the browser auto-refreshes after a livereload trigger the log messages don't appear?

Yes, that's correct.

If so, does the livereload js script atleast get loaded by the browser in those cases?

As far as I can tell, livereload.js doesn't get loaded in those cases. Here's what's listed in the Network tab of Chrome, when I do a manual refresh and then when it auto-reloads:

Manual refresh:

/assets/js/main.js
code.jquery.com/.../jquery-2.1.1.min.js
use.typekit.net/.../thp8zyr.js
livereload.js
socket.io.js

On auto-reload (upon the livereload trigger):

code.jquery.com/.../jquery-2.1.1.min.js
/assets/js/main.js
use.typekit.net/.../thp8zyr.js

It appears that neither livereload.js nor socket.io.js are loaded in Chrome when it refreshes due to the livereload trigger.

hiddentao commented 8 years ago

That is very very strange. I am unable to reproduce it so the only way to figure this out would be to stick some console.logs into the library code at key points and see that the livereload.js script is being injedted each time. By the way, what version of the package are you using?

kentr commented 8 years ago

@hiddentao:

Version 1.8.1

stick some console.logs into the library code at key points and see that the livereload.js script is being injedted each time.

I can do that. Where do you suggest putting them?

hiddentao commented 8 years ago

This is the line which generates the injection snippet -> https://github.com/hiddentao/gulp-server-livereload/blob/master/src/index.js#L131

And then it actually injects it here -> https://github.com/hiddentao/gulp-server-livereload/blob/master/src/index.js#L148

kentr commented 8 years ago

It looks like the code isn't getting injected when a change happens. Possibly, this module's index.js isn't running at all at those events.

I added the logging as so in gulp-server-livereload/src/index.js (snippet starting at line 132):

    var snippet =
      "<script type=\"text/javascript\">"
      + "var _lrscript = document.createElement('script');"
      + "_lrscript.type = 'text/javascript';"
      + "_lrscript.defer = _lrscript.async = true;"
      + "_lrscript.src = '//' + ((" + markupHost + "||location.host).split(':')[0]) + ':"+config.livereload.port+"/livereload.js?"+snippetParams.join('&')+"';"
      + "document.body.appendChild(_lrscript);"
      + "</script>";

    console.log('livereload snippet', snippet);

    var prepend = function(w, s) {
      console.log('livereload prepend()', w);
      return s + w;
    };

    var append = function(w, s) {
      console.log('livereload append()', w);
      return w + s;
    }

Resulting logs in the console:

With Safari, I see the notice that the file changed and the log message from prepend:

[13:50:09] Livereload: file changed: /Users/Kent/eclipse workspace/Bootstrap-to-Wordpress/index.html
livereload prepend() </body>
[13:50:09] Livereload client connected

With Chrome, I see the notice that files changed, but none of the additional logging:

[11:24:34] Livereload: file changed: /Users/Kent/eclipse workspace/Bootstrap-to-Wordpress/index.html
hiddentao commented 8 years ago

Looks like Chrome isn't always requesting the HTML page. What we need is to force it to do this.

If you open chrome's developer tools you should be able to disable cacheing in there (it's one of the option in the Network tab). Can you try repeating the above refresh flow with Chrome's developer tools window open and visible? I imagine it will work better.

kentr commented 8 years ago

Disabling the Chrome cache in dev tools appears to solve it.

On Jul 5, 2016, at 10:37 PM, Ramesh Nair notifications@github.com wrote:

Looks like Chrome isn't always requesting the HTML page. What we need is to force it to do this.

If you open chrome's developer tools you should be able to disable cacheing in there (it's one of the option in the Network tab). Can you try repeating the above refresh flow with Chrome's developer tools window open and visible? I imagine it will work better.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/hiddentao/gulp-server-livereload/issues/15#issuecomment-230675375, or mute the thread https://github.com/notifications/unsubscribe/AAJODOfIvzdURyl37fodoSPp4cFG11Q7ks5qSz8kgaJpZM4FRSwF.

hiddentao commented 8 years ago

I'm not sure how to fix this from the plugin's side. If Chrome doesn't re-request the index/html page we can't inject the livereload script.

kentr commented 8 years ago

Is the server based on the html module? I was poking around in the docs, and it looks like there is a way to set outgoing Cache-Control headers.

So, perhaps the header could be set to Cache-Control: no-cache, no-store, must-revalidate

hiddentao commented 8 years ago

@kentr Good idea. Would you be able to help me test out the following snippet and let me know if it works?

  app.use(function(req, res, next) {
    res.header("Cache-Control", "no-cache, no-store, must-revalidate");
    res.header("Pragma", "no-cache");
    res.header("Expires", 0);

    next();
  });

Please place it after the var app = connect(); line.

(Also, you'll need to make sure dev tools cacheing if turned off to check that it works).

uniquejava commented 8 years ago

@hiddentao Hi, I tried to modify your src/index.js as you proposed, when I run gulp webserver, there is the following errors:

TypeError: res.header is not a function
    at /Users/cyper/learn-bootstrap/node_modules/gulp-server-livereload/src/index.js:104:9
    at call (/Users/cyper/learn-bootstrap/node_modules/gulp-server-livereload/node_modules/connect/lib/proto.js:205:7)
    at next (/Users/cyper/learn-bootstrap/node_modules/gulp-server-livereload/node_modules/connect/lib/proto.js:149:5)
    at Function.app.handle (/Users/cyper/learn-bootstrap/node_modules/gulp-server-livereload/node_modules/connect/lib/proto.js:152:3)
    at Server.app (/Users/cyper/learn-bootstrap/node_modules/gulp-server-livereload/node_modules/connect/lib/connect.js:28:37)
    at emitTwo (events.js:87:13)
    at Server.emit (events.js:172:7)
    at HTTPParser.parserOnIncoming [as onIncoming] (_http_server.js:528:12)
    at HTTPParser.parserOnHeadersComplete (_http_common.js:88:23)

I console.log the res object, it does not have header method. 😦

ServerResponse {
  domain: null,
  _events: { finish: [Function: resOnFinish] },
  _eventsCount: 1,
  _maxListeners: undefined,
  output: [],
  outputEncodings: [],
  outputCallbacks: [],
 ....
uniquejava commented 8 years ago

@hiddentao @kentr Hi, I replaced the header(...) method with setHeader(...) and it worked. The chrome browser is able to auto reload the page each time I save a file (without the need to disable cache in chrome dev tools)

  app.use(function(req, res, next) {
    res.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
    res.setHeader("Pragma", "no-cache");
    res.setHeader("Expires", 0);

    next();
  });
hiddentao commented 8 years ago

@uniquejava Thanks a lot, will merge and publish now.

hiddentao commented 8 years ago

1.8.2 published.