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

When a frame fails to load due to a mixed content issue, the main Page is never considered loaded. #1936

Closed
BenoitZugmeyer opened this issue Jan 31, 2018 · 6 comments
Labels

Comments

@BenoitZugmeyer
Copy link
Contributor

BenoitZugmeyer commented Jan 31, 2018

Steps to reproduce

Tell us about your environment:

  • Puppeteer version: 1.0.0
  • Platform / OS version: ArchLinux (up to date)
  • URLs (if applicable): https://pste.eu/p/awIC.html
  • Node.js version: 9.4.0

What steps will reproduce the problem?

Try to load a HTTPS URL including an iframe with a HTTP src (normally blocked with a message like: Mixed Content: The page at '...' was loaded over HTTPS, but requested an insecure resource '...'. This request has been blocked; the content must be served over HTTPS.)

Check this example:

"use strict";
const puppeteer = require("puppeteer");
const url = "https://pste.eu/p/awIC.html";

(async () => {
    const browser = await puppeteer.launch({
        args: [ "--no-sandbox", "--disable-gpu" ]
    });
    const page = await browser.newPage();
    await page.goto(url);
    await browser.close();
})();
Content of https://pste.eu/p/awIC.html
<!DOCTYPE html>
<html>
<head>
    <title></title>
    <meta charset="utf-8" />
</head>
<body>
    <iframe src="http://github.com/"></iframe>
</body>
</html>

What is the expected result?

The page loads. page.goto(...) returns a resolved promise.

What happens instead?

The page never loads. page.goto(...) returns with a rejected promise after a 30 seconds timeout (Error: Navigation Timeout Exceeded: 30000ms exceeded).

Notes

As far as I understand, this is because the iframe never triggers the load event, and the NavigatorWatcher iterates over all iframes to check if a load event occured before resolving the navigationPromise. This issue may need some devtools protocol additions to be fixed.

@BenoitZugmeyer
Copy link
Contributor Author

Shower thought: on top of this, it would be great to have a "requestfailed" event triggered, in the same way loading a script with a mixed content issue fails.

@GregRos
Copy link

GregRos commented Feb 5, 2018

To be honest, I've found the promise returned by goto to be pretty unreliable in general. I've resorted to injecting some code that manually subscribes to events like DOMContentLoaded and load.

@iszmidt
Copy link

iszmidt commented Mar 12, 2018

I'm having the same issue. You can try this workaround:

"use strict";
const puppeteer = require("puppeteer");
const url = "https://pste.eu/p/awIC.html";

(async () => {
    const browser = await puppeteer.launch({
        args: [ "--no-sandbox", "--disable-gpu" ]
    });
    const page = await browser.newPage();
    await page.evaluate((url)=>{window.location = url}, url);
    await page.waitFor('body > iframe');
    console.log('working!');
    await browser.close();
})();

@distante
Copy link

distante commented Mar 21, 2018

I'm having the same issue. You can try this workaround:

"use strict";
const puppeteer = require("puppeteer");
const url = "https://pste.eu/p/awIC.html";

(async () => {
    const browser = await puppeteer.launch({
        args: [ "--no-sandbox", "--disable-gpu" ]
    });
    const page = await browser.newPage();
    await page.evaluate((url)=>{window.location = url}, url);
    await page.waitFor('body > iframe');
    console.log('working!');
    await browser.close();
})();

This allow the page to load but there is no way to capture the error.

@panthony
Copy link

panthony commented Apr 6, 2018

Same issue, tried --allow-running-insecure-content with no luck.

@GregRos Can you somewhat retrieve a response using this method? What was the status code, the HTTP headers, etc?

How do you navigate without goto? Do you use evaluate(() => window.location = url)?

Edit:

I tried something like this instead of using goto, does the work, probably not be bulletproof

    return new Promise((resolve) => {
      let returnValue = null;

     page.on('response', (response) => {
        if (returnValue === null) {
          returnValue = response;
        }
      })

     page.on('domcontentloaded', () => {
        resolve(returnValue);
      })

      return page.evaluate((url) => window.location = url, url);
    });

aslushnikov added a commit to aslushnikov/puppeteer that referenced this issue Apr 10, 2018
This patch teaches Page.waitForNavigation to correctly handle navigation
to pages that have frames that might never load.

These frames include:
- frames which main resource loading was aborted due to mixed-content
  error
- frames that artificially called `window.stop()` to interrupt loading
  themselves

Fixes puppeteer#1936.
aslushnikov added a commit that referenced this issue Apr 10, 2018
…nt (#2339)

This patch teaches Page.waitForNavigation to correctly handle navigation
to pages that have frames that might never load.

These frames include:
- frames which main resource loading was aborted due to mixed-content
  error
- frames that artificially called `window.stop()` to interrupt loading
  themselves

Fixes #1936.
@elainema
Copy link

To be honest, I've found the promise returned by goto to be pretty unreliable in general. I've resorted to injecting some code that manually subscribes to events like DOMContentLoaded and load.

Could u pls share that ?

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

No branches or pull requests

7 participants