问题
While testing images being loaded from an email in my iOS Outlook app, I see inconsistencies with how the app caches them. These images are loading from external sources (i.e. HTML img
tag with src
pointing to a server, not images that are embedded/attached). The app makes several requests to the same image source as you navigate around. Some of these requests contain the HTTP_IF_NONE_MATCH
header but there is a lot of inconsistency. I don't think it's caching them correctly. I've included more details below. it looks like it's causing my image to be loaded several times when the person is browsing the email/their inbox.
The reason this is a problem for me is that I'm building an email tracking tool that relies on a pixel tracker inside the email. I'm trying to determine how many times my email is opened by its various recipients. So this inconsistency is causing misfires for the tool unfortunately. While I realize that could be considered consequential limitation of relying on the app, I'm wondering if the lack of image caching is a larger issue that could be addressed. It is effectively firing requests to load the image repeatedly so that is eating up mobile data unnecessarily.
Is there a way to improve its caching somehow? I'm also looking for any other ways to determine requests coming from the same phone. Here's what I see in my server log when dealing with an email that contains my pixel tracker.
- Push notification for email received on iPhone
- Click the app to load the inbox -> Tracker request fired for 1st time (i.e. image loaded for first time)
- Open email -> Tracker request fired for 2nd time (without any
HTTP_IF_NONE_MATCH
header) - Go back to inbox -> Tracker request fired for 3rd time but this time it includes
HTTP_IF_NONE_MATCH
header. Note previous requests did not include this header even though it's the same URL so some inconsistency indicating it did not cache it - Open email for the second time -> Tracker request fired for 4th time but it did not include the
HTTP_IF_NONE_MATCH
header (inconsistency with 3rd time, which had header) - Go back to inbox -> No request fired
- Open email for third time -> Tracker request fired for 5th time and it included
HTTP_IF_NONE_MATCH
header (so inconsistency between this and 4th request, which did not include it)
From here on, repeating any of the above steps would trigger requests but would always include the HTTP_IF_NONE_MATCH
header successfully. I also tested changing folders, refreshing the inbox, replying to emails etc. While this triggered tracker requests as well, they also included the appropriate header.
However, I noticed that closing the app (by swiping it off) and then opening it again effectively caused the behaviour to reset. The 1st, 2nd and 4th requests would still not include the header while the others would. Note the same happens on data vs wifi.
Generally speaking, it looks like the iOS app is repeatedly loading the images that it should have already cached. Outlook desktop clients work great because it only fires 1 request to load the pixel. For the Outlook Android app, it seems to do a better job caching the image. It makes 2 or 3 requests the first couple of times you open the email but the 2nd/3rd requests always include the header. After that, it stops loading the image altogether so it must be caching it on the phone somehow. Since the Android app functions fairly differently, this is what lead me to believe it may be an issue that could be resolved in the app itself. However, as I said above, I'm looking for alternative ways to determine how to track the user.
Another way I normally rely on is to set a cookie to indicate an open just happened by that device. I then simply skip these false positives to avoid the repeated requests. However, because of the nature of iOS apps needing to whitelist third-party cookies of web requests within the code, each subsequent request is not sending my cookie along either. Here's a related question as well. I confirmed the Safari settings do not block 3rd party cookies in case it conflicts.
Alternatively, if there's another way to tell a unique device, I could figure out how to skip repeated opens for that phone on the server. I checked the rest of the request headers. The only thing that's somewhat identifiable is a combination of user-agent and IP address but that seems very unreliable to me. Two people in the same office with the same corporate phone could be on the same wifi so I think that would fire false negatives instead.
Is there another way to determine the device is opening it multiple times? Ideally if it sent a unique identifier or something, that would be very useful.
Is there a way to force the app to cache the image (this would heavily reduce the misfires) via say some response header?
来源:https://stackoverflow.com/questions/61924058/images-in-emails-are-inconsistently-being-cached-in-ios-outlook-app