Usually, we only use the IMG tag or Image object to load Image resources, but in practice Image is often used to make requests for data reporting, partly because cross-domain considerations are not required, and usually data reporting does not require a response. However, if you use Image in your code to send some business requests, for example, then you need to consider the necessity, and if you don’t, you should use Ajax to send the request, otherwise you can create a hidden hole.

background

Recently, I took over a bug in which the balance of user feedback was not displayed. Since I could not reproduce the bug under the condition of existing information, and it was difficult to find the logic problem from the code (or lack of experience), I had to find users to cooperate with the joint investigation by logging. It took several days to finally locate the bug caused by using image to send requests. So how does using image to send requests cause this bug? What are the hidden dangers?

The screening process

First, take a look at the screenshot of the user feedback :(which has a key message implicit)

Logon status problem

By checking the background log information of the user, it was found that a key ticket information was missing in the Cookie of the user’s account information request, resulting in the failure to obtain the balance. Therefore, it was found that the request to obtain the ticket was not found in the log. Therefore, it can be judged that the user cannot get the balance information because of the login status problem. However, why did the background not receive the key ticket request?

Has the request been sent yet?

When a request is not received by the background, the first suspect is a logical problem: there should be a logical loophole that causes the request not to be sent under certain conditions. Then, through local debugging and combing through the logic, there is no actual possibility that the request will not be sent. At this point, it’s hard to move on without more information, and the business logic is almost certainly fine. However, I’m starting to wonder why Image is used here:

var imgReq = document.createElement('img');
imgReq.onload = imgReq.onerror = function() {... } imgReq.src = url;Copy the code

Log more

Even if you can tell in theory that the logic is fine just by looking at the code, there is no way to guarantee that it will work. I had no choice but to type more logs into the code, then contact the user for operation, and send me the logs printed by the vconsole on the phone (this is OTZ that requires the user’s cooperation very much). Fortunately, the user cooperated and followed my instructions, and I was able to get the user’s mobile client logs for analysis.

Based on the log, I’m sure the request must have been sent, but the server did not receive it. This made me feel weird, and I began to suspect img. SRC was the problem, and was horrified to find that ** users’ avatars were not displayed! ** That’s the key message! At first, I thought the user’s profile picture was gray, so I didn’t pay attention to it, but in the QQ group that communicates with users, users have profile pictures. It’s not hard to imagine that this most likely has something to do with the browser’s graphless mode. However, it still doesn’t work on my phone, so I’m left with this assumption:

  1. Depending on the type of phone;
  2. Related to graphless mode and image request;

With this assumption in mind, I added an Ajax request and had to ask the user to try again, which was soon confirmed in the log:

. cookie: ... // No ticket (after img request)... cookie: ... // There are tickets (after an Ajax request)Copy the code

So I repeated the problem on the same phone… (Why not find a phone with the same model earlier to reproduce 😭 OTZ)

The case

In the browser without picture mode (here the specific scene is QQ browser), and on some mobile phones, it is possible to intercept requests dynamically initiated by Image! It’s ok for a report request to be blocked (after all, how many people care about traffic these days), but a business request to be blocked can directly affect functionality. To avoid such hidden dangers, we should try to avoid using Image to send business requests.