cookies have one advantage over localStorage and custom headers though: They can be set by the server in a way that client-side JS code doesn't get to see or change them.
This makes abusing XSS vulnerabilities to get to the token slightly harder.
"Slightly harder" is right. You can always write a non-JS client app, e.g., using Apache HttpClient. At that point the client can do anything it wants with headers.
This makes abusing XSS vulnerabilities to get to the token slightly harder.