Method 3 is particularly interesting, IMO, because it's a short term + long-term solution. However, all of them seem to suffer from non-permanence. That is, they all have the issue that the contract owner can just randomly choose to screw you over later. With Method 1, they could just change the URI altogether to something you didn't buy. Methods 2 and 3 may do the same thing, and method 2 in particular seems like it defeats some of the major purposes of web3 to begin with.
I understand this would match the gas efficiency of Method 1, but wouldn't it be best for mint() to accept the token URI and store it as an immutable value?