Safari: "Blocked https://... from asking for credentials because it is a cross-origin request." after updating to Angular 8

Viewed 4970

We have secured our Angular web app with Basic Auth. After updating our app from Angular 7 to 8.0, we are no longer asked for the credentials in Safari and the following errors appear in the console:

[Error] Blocked https://*/runtime-es2015.4f263ec725bc7710f1f5.js from asking for credentials because it is a cross-origin request.
[Error] Blocked https://*/main-es2015.6fa442dd5c5a204f47da.js from asking for credentials because it is a cross-origin request.
[Error] Blocked https://*/polyfills-es2015.fd951ae1d7572efa3bc6.js from asking for credentials because it is a cross-origin request.

In Firefox and Chrome the app still runs without problems. Safari version is 12.1.1.

Does anyone have any idea what the problem with Safari is?

4 Answers

Since angular/cli 8.1 (PR) there is a option crossOrigin for the ng build command (documentation). Possible values are: none | anonymous | use-credentials (defaults to none).

Using this option will alter the script tags in index.html to add the crossorigin attribute.

You can either use this temporary for a build using: ng build --crossOrigin=anonymous

Or use the option in your angular.json under architect.build.options:

"architect": {
    "build": {
      "builder": "@angular-devkit/build-angular:browser",
      "options": {
        "crossOrigin": "anonymous", // <-- set value here
        // other options

It seems like some changes of the module scripts spec (https://github.com/whatwg/html/pull/3656) has not been yet implemented in Safari. For me it works on Safari Technology Preview.

In the meantime, you can fix it by adding the crossorigin attribute on your module scripts, like this:

<script src="runtime-es2015.ff56c41ec157e6d9b0c8.js" type="module" crossorigin></script>

Here is the solution I have adopted (requires one third party package).

First, install this custom webpack builder: @angular-builders/custom-webpack:

npm i -D @angular-builders/custom-webpack

Be sure to check the prerequisites in its readme and update other dependencies as needed.

Update your angular.json to make use of the builder and set the indexTransform option:

"projects": {
  ...
  "your-app": {
    ...
    "architect": {
      ...
      "build": {
        "builder": "@angular-builders/custom-webpack:browser"
        "options": {
            "indexTransform": "./index-html-transform.js"
              ...
        }

Finally, create a file named index-html-transform.js in the root directory of your project with the following contents:

module.exports = (targetOptions, indexHtml) => {
  const regex = /(<script.*?type="module".*?)>/gim;
  return indexHtml.replace(regex, "$1 crossorigin>");
};

Now, when you build your app and the index.html is emitted, it will automatically add the crossorigin attribute to every module script.

My solution is to add --subresource-integrity flag when building:

ng build --subresource-integrity

This flag also adds crossorigin attribute to module scripts according to this comment.

I have the same issue with Angular 8. To fix the issue I just edited my tsconfig.json as it was with Angular 7:

{
  ...
  "compilerOptions": {
    ...
    "module": "es2015",
    ...
    "target": "es5",
    ...
  }
}
Related