This paper is published in 10, 2018-1, 2020-1
Some time ago, I reconstructed a page, and there were dynamic advertisements inserted through third-party JavaScript codes (normal product requirements) on the page. After I went online, I found that there were repeated requests for third-party advertising resources. Since the JavaScript code controlling the advertisement insertion was provided by a third party, we were only responsible for introducing it in accordance with their requirements, so we did not know the content of the third-party advertisement code. In this case, we started the difficult investigation process. Although it was difficult, the cause was finally found. In this process, some gains were made. Now the investigation process is abstracted as follows:
Note: The following process is done in Chrome.
First, sample code
<div id="container">
<iframe src="/iframe-1" frameborder="0"></iframe>
<iframe src="/iframe-2" frameborder="0"></iframe>
<iframe src="/iframe-3" frameborder="0"></iframe>
</div>
<script>
document.getElementById('container').innerHTML += ' Above is iframe
';
</script>
Copy the code
Three IFrames are rendered on the page, and a p element is appended to the last iframe
Second, the phenomenon of
1. Page: Render normally
2.Network: Status canceled is canceled.
Three, the investigation process
1. Where do repeated requests come from?
Since it is to solve the problem of repeated requests, then where repeated requests come from is the first problem we have to solve. Since the request is made from a third party’s JavaScript code, reading a third party’s compressed JavaScript code is more like a headless chicken. The whole process is like wandering outside the siege, anxious. Later, I calmed down and found a key troubleshooting tool in Chrome devTools: Initiator under Network
What does this column mean? In layman’s terms, this is the location where the request is triggered. By comparison, it is found that the same repeated request is initiated in different locations. Take/ifame -1 as an example: Click Initiator of the first request, and the jump location (marked yellow) is as follows:
Click the Initiator of the second request and jump to the location (marked yellow) :
You can observe that the first/IFame-1 request is triggered automatically due to normal rendering of the IFrame element, and the second/ifame-1 request is triggered when JavaScript code is executed (to concatenate DOM nodes), However, for the line of JavaScript that triggers the second /iframe-1 request, the real intention is simply to concatenate a P element, and nothing extra (such as triggering a new request) is expected to happen. In addition, the second request for/ifame -2 and/ifame -3 is triggered by the JavaScript code that concatenates the DOM nodes. Now that the culprit is clear, let’s examine the cause of the repeated request.
2. Why repeated requests?
JavaScript code that generates repeated requests
document.getElementById('container').innerHTML += ' Above is iframe
';
Copy the code
Translated into:
document.getElementById('container').innerHTML = document.getElementById('container').innerHTML + ' Above is iframe
';
Copy the code
Get all the innerHTML of the div element with the container id, concatenate it with the p element, and assign the value to the innerHTML of the container.
This process causes the iframe element to be rerendered, which in turn causes the iframe request to be refired.
So, the same iframe triggers two requests: rendering the iframe element when the page is first loaded triggers the first request, and executing DOM splicing code causes the iframe to be re-rendered triggers the second request.
Key point: Assigning the innerHTML of a DOM element results in rendering the spliced element (3 iframes +1 P).
If you find the cause of the problem, the solution to the problem will come naturally. Change the above code to:
var div = document.createElement('div');
var text = document.createTextNode('advertising');
div.appendChild(text);
document.getElementById('container').appendChild(div);
Copy the code
That solved the problem, but there was still a question: Why did rendering iframe produce the first request with a canceled status?
3. Why is Status canceled for repeated requests?
First of all, what does’ Status’ mean? Canceled canceled means that the request was canceled by the browser before it was sent to the server. That means that the request never made it from the browser at all, let alone reached the server.
Why was the first request cancelled by the browser? Google Google with the keyword “Chrome Cancel request” and found a fairly comprehensive answer on Stack Overflow, as shown in the screenshot below:
Here are some scenarios where Chrome cancels a request:
- The DOM element that triggered the request was removed (e.g., the IMG element was removed before it finished loading)
- Did some unnecessary data loading (such as changing the SRC of the iframe after starting to load or overwriting its contents)
- A large number of requests are directed to the same server, and network problems with previous requests indicate that subsequent requests are not working either (DNS query error, previous request message 400).
The case of this article falls into the second scenario. At this point, the whole process of the point of doubt one by one.
Four,
Now review this bug, the cause is not deep, but the whole troubleshooting process is worth summarizing. To summarize:
1. For third-party library errors, do not try to solve the problem by reading through and familiar with the whole library, reading through the code will only waste time to solve the problem, understand the call relationship is king
2. Network > Initiator in Chrome developer tools indicates where the request is triggered, which is useful for locating requests, especially those from third-party libraries
3. The request status canceled indicates that the request was canceled by the browser. The request was not sent out of the browser and couldn’t enter the server
4. See the figure above for several scenarios in which Chrome cancels the request
5. Element. innerHTML += HTMLStr Splices the original child node with the new node and renders it again. Use caution when the node content contains an IFrame