Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Disabling automatic bootstrap. <script> protocol indicates an extension, document.location.href does not match #15567

Closed
jeffhuys opened this issue Jan 2, 2017 · 14 comments

Comments

@jeffhuys
Copy link

jeffhuys commented Jan 2, 2017

Do you want to request a feature or report a bug?

Bug

What is the current behavior?

On certain browsers (Tested: Safari 9, PhantomJS 2.1), Angular refuses to bootstrap. It generates the error: Angular: Disabling automatic bootstrap. <script> protocol indicates an extension, document.location.href does not match.

If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem via https://plnkr.co or similar (template: http://plnkr.co/edit/tpl:yBpEi4).

I find it very hard to debug this issue and reproduce it. What might help: we're using Webpack to compile everything down to a single <script> tag (WITHOUT src= or anything else)

What is the expected behavior?

I expect angular to auto-bootstrap.

What is the motivation / use case for changing the behavior?

It's very weird that different browsers generate different results. We're already in production and only now we're getting reports of people being unable to open our website.

Which versions of Angular, and which browser / OS are affected by this issue? Did this work in previous versions of Angular? Please also test with the latest stable and snapshot (https://code.angularjs.org/snapshot/) versions.

WORKS in macOS Sierra with Safari 10.x, Firefox, Chrome.
BROKEN in macOS with Safari 9.x, PhantomJS, SINCE 1.5.9

Other information (e.g. stacktraces, related issues, suggestions how to fix)

I've traced the code to https://github.com/angular/angular.js/blob/master/src/Angular.js#L1509 .

Maybe I need to specify a src= tag, or something?

I'm aware that this report may miss some critical info. Please let me know what other information you need!

@Narretz
Copy link
Contributor

Narretz commented Jan 2, 2017

This might be a false positive for the mechanism that disallows bootstrap if "angular.js was loaded from a known scheme used on the web". It's possible that there is no provision for a script tag without a src attribute.
Can you maybe debug were exactly this function here:

function allowAutoBootstrap(document) {
returns false, and why in your application?

@gkalpak
Copy link
Member

gkalpak commented Jan 3, 2017

cc @mprobst

@mprobst
Copy link
Contributor

mprobst commented Jan 3, 2017

@jeffhuys could you change the code to print out document.location.origin and link.origin (and possibly without the .origin as well)?

https://github.com/angular/angular.js/blob/master/src/Angular.js#L1485

This is probably some incompatibility on our side, but it's unclear to me what values we should expect there in Safari & PhantomJS.

@gkalpak
Copy link
Member

gkalpak commented Jan 3, 2017

Obviously, document.currentScript.getAttribute('src') returns null when there is no src attribute. The difference comes from how different browsers treat link.href = null.

Chrome (and presumably the other working browsers) treats it as link.href = 'null', which sets the link.protocol and link.origin correctly.

PhantomJS (and presumably Safari 9.x) seems to ignore it. As a result, link.href === link.origin === '' and link.protocol === ':'.

An easy fix would be changing this line like this (which seems to work on PhantomJS):

-var src = document.currentScript.getAttribute('src');
+var src = document.currentScript.getAttribute('src') || '';

The following might also work, but I haven't tried it on all browsers:

-var src = document.currentScript.getAttribute('src');
+var src = document.currentScript.src;

@gkalpak
Copy link
Member

gkalpak commented Jan 3, 2017

@mprobst, if this sgty, I can put together a PR (unless @jeffhuys wants to 😉).

@mprobst
Copy link
Contributor

mprobst commented Jan 3, 2017

@gkalpak sounds reasonable. We should treat no src= attribute as the <script> coming from the same origin as the document. Which means we could also check and early exit, something like if (!src) return true;.

gkalpak added a commit to gkalpak/angular.js that referenced this issue Jan 3, 2017
Some browsers (e.g. Safari 9.x, PhantomJS) do not set `link.origin/protocol`
correctly, when setting `link.href` to `null`, which prevented auto-bootstraping
Angular from scripts without a `src` attribute (i.e. inline scripts).
Inline scripts are on the same origin as the loading page, so auto-bootstraping
should be allowed.

Fixes angular#15567
@gkalpak gkalpak closed this as completed in 0694af8 Jan 3, 2017
gkalpak added a commit that referenced this issue Jan 3, 2017
Some browsers (e.g. Safari 9.x, PhantomJS) do not set `link.origin/protocol`
correctly, when setting `link.href` to `null`, which prevented auto-bootstraping
Angular from scripts without a `src` attribute (i.e. inline scripts).
Inline scripts are on the same origin as the loading page, so auto-bootstraping
should be allowed.

Fixes #15567

Closes #15571
gkalpak added a commit that referenced this issue Jan 3, 2017
Some browsers (e.g. Safari 9.x, PhantomJS) do not set `link.origin/protocol`
correctly, when setting `link.href` to `null`, which prevented auto-bootstraping
Angular from scripts without a `src` attribute (i.e. inline scripts).
Inline scripts are on the same origin as the loading page, so auto-bootstraping
should be allowed.

Fixes #15567

Closes #15571
@gkalpak
Copy link
Member

gkalpak commented Jan 3, 2017

@jeffhuys, can you confirm that the fix in #15571 works for your app?

@jeffhuys
Copy link
Author

Guys, so sorry I haven't responded yet! We're currently checking if this fix works. Will report back! Thanks so much and sorry again.

@McGiogen
Copy link

Today we found the same problem on IE11 in our production site. We upgraded angularjs from 1.5.9 to 1.5.11 but this didn't fix the problem. We solved disabling automatic bootstrap as stated here.

@mgol
Copy link
Member

mgol commented Feb 10, 2017

@McGiogen please report an issue describing how you load AngularJS, preferably with a test case (and link to it from here), if we have any bugs in the algorithm deciding whether to allow autobootstrap, we'd like to fix them.

ellimist pushed a commit to ellimist/angular.js that referenced this issue Mar 15, 2017
Some browsers (e.g. Safari 9.x, PhantomJS) do not set `link.origin/protocol`
correctly, when setting `link.href` to `null`, which prevented auto-bootstraping
Angular from scripts without a `src` attribute (i.e. inline scripts).
Inline scripts are on the same origin as the loading page, so auto-bootstraping
should be allowed.

Fixes angular#15567

Closes angular#15571
@Wolfke85
Copy link

The problem is with

if (document.location.origin === link.origin) {

IE 11 does not add the origin header in some cases: http://stackoverflow.com/questions/20784209/internet-explorer-11-does-not-add-the-origin-header-on-a-cors-request

@gkalpak
Copy link
Member

gkalpak commented Mar 23, 2017

@Wolfke85, IE11 should not have document.currentScript in the first place, so the line you mention should never be reached.

@Wolfke85
Copy link

@gkalpak We do reach that line, since after some investigation we use PDFJS (https://github.com/mozilla/pdf.js) which has a compatibility.js where they do the following:

// Provides document.currentScript support
// Support: IE, Chrome<29.
(function checkCurrentScript() {
  if ('currentScript' in document) {
    return;
  }
  Object.defineProperty(document, 'currentScript', {
    get: function () {
      var scripts = document.getElementsByTagName('script');
      return scripts[scripts.length - 1];
    },
    enumerable: true,
    configurable: true
  });
})();

@gkalpak
Copy link
Member

gkalpak commented Mar 24, 2017

@Wolfke85, this dicussed in #15772.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants