However, if the salt has been exposed then it's the same thing as not using one...
That's not how salts work. The point is that an attacker can do a lot of effort in advance to generate a massive rainbow table containing the hashes of a large set of possible passwords (or in practice, simply pay for access to such a service).
By adding a random nonce (i.e. the salt) to passwords before hashing them, you force the attacker to include all possible nonce values in those passwords. For each extra bit in the nonce, you double the size the rainbow table, quickly making it infeasible to generate one.
So even if the salt is public, it will still do its job in preventing the use of rainbow tables. The attacker will be forced to brute-force by trying all possible passwords in combination with a given nonce just to crack a single password hash.
If that's the case then salting can/should be improved. I believe that the more secure method would be to keep a lengthy pseudo-random salt a secret, in a datastore that is physically separated from the application DB. You begin by hashing the user's password with a well known algorithm. That output will then be hashed again with the pseudo-random salt added to it. By doing this you would force the attacker to guess at (or create rainbow tables) for not just the password but for each password they would then need to build a table for that output plus each guess at the salt.
If the salt is long, pseudo-random, and unknown then it would seem that this would be more secure. Keeping the salt in a separate datastore where only the logon provider has access to it would thereby make it more difficult for an attacker to gain access to the salt. Even if they gain access to the computer hash outputs.
My thoughts, perhaps they are wrong...