sitespeedio / chrome-har

Create HAR files from Chrome Debugging Protocol data
MIT License
149 stars 50 forks source link

Missing requests in iFrame within iFrame #66

Closed mikedijkstra closed 4 years ago

mikedijkstra commented 4 years ago

I've come across an issue where requests are being omitted from an iFrame in an iFrame.

I've created a reproducible case where an image (img_girl.jpg) is missing from the generated HAR, even though it is in the devtools logs.

How to reproduce

  1. Generate a devtools log for this URL: https://qduej.csb.app/ See devtools log
  2. Generate a HAR using the devtools log See HAR Logging the request IDs you can see the following:

Going through the devtools log you can see that there are no Page.frameAttached events for the second iframe, despite a Network.requestWillBeSent event referring to the frameId 25A2EF16DA63D669E56F8639E5EFE72C.

  {
    "method": "Network.requestWillBeSent",
    "params": {
      "requestId": "A96E1426CD51C4AC5E90C43EE09F3C23",
      "loaderId": "A96E1426CD51C4AC5E90C43EE09F3C23",
      "documentURL": "https://zfh61.csb.app/",
      "request": {
        "url": "https://zfh61.csb.app/",
        "method": "GET",
        "headers": {
          "Upgrade-Insecure-Requests": "1",
          "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36",
          "Referer": "https://deploy-preview-26--michaeldijkstra-netlify-test.netlify.app/"
        },
        "mixedContentType": "none",
        "initialPriority": "VeryHigh",
        "referrerPolicy": "no-referrer-when-downgrade"
      },
      "timestamp": 162823.851228,
      "wallTime": 1590380010.679388,
      "initiator": {
        "type": "parser",
        "url": "https://deploy-preview-26--michaeldijkstra-netlify-test.netlify.app/",
        "lineNumber": 6
      },
      "type": "Document",
      "frameId": "25A2EF16DA63D669E56F8639E5EFE72C",
      "hasUserGesture": false
    },
    "source": {
      "targetId": "B6C52BA4191283DB2B514A0AA6507C5A",
      "sessionId": "1F88229A0F0DA12B6ADECDE9D3134F15"
    }
  }

This could well be a bug in Chromium as when I was trying to reproduce the issue I noticed that if the first iframe was on the same domain it would create the Page.frameAttached event but when it's on a different domain it doesn't.

I still think it'd be good to show these events in the HAR as they are happening.

The block of code which ultimately removes the entry is during Network.responseReceived and it can't be matched to a page:

const frameId = rootFrameMappings.get(params.frameId) || params.frameId;
const page = pages.find((page) => page.__frameId === frameId);
if (!page) {
  debug(
    `Received network response for requestId ${params.requestId} that can't be mapped to any page.`
  );
  continue;
}

I noticed that when processing Network.requestWillBeSent the last page is used, which was added to support multi page hars in PR #30

const page = pages[pages.length - 1];

Do you think we can do something similar to this? Where we look for the page but fallback to the last page?

const page = pages.find((page) => page.__frameId === frameId) || pages[pages.length - 1];

I'm not sure of the reasoning behind filtering the events out or what the repercussions of doing this as a fallback would be.

Again, happy to work on a PR for this if we think there's a good way forward!

soulgalore commented 4 years ago

Hi @mikedijkstra yes a PR is very welcome. If you also can add a trace in the tests with that behaviour so that we don't break it in the future that would be great.