Don't use JSONP at all - use CORS.
JSONP is obsolete and has always been more of a hack fill-in than a thought-out technology for resource sharing. The modern and widely supported alternative is CORS (Cross-Origin Resource Sharing). You will most certainly be able to replace all your JSONP use cases with it.
With CORS, you don't need to wrap your JSON in a callback function anymore (e.g. cb({"foo": "bar"})
), but keep it as is. Instead, you send an Access-Control-Allow-Origin
header to indicate to the browser which origins you want to give access. Since every CORS-capable browser sends an Origin
header in their cross-origin requests, you can produce the ACAO header dynamically, depending on where the request came from. Once permitted, the client will be able to read the response content, no matter what content type. So you can just use send regular JSON.
Sample cross-origin request from supplicant.example
to a JSON API at server.example
:
GET /foo.json HTTP/1.1
Host: server.example
...
Origin: https://supplicant.example
...
Sample response:
HTTP/1.1 200 OK
....
Access-Control-Allow-Origin: https://supplicant.example
Content-Type: application/json
...
{"foo": "bar"}
Not only does CORS provide better security over JSONP, but it gives you the ability to work with arbitrary HTTP methods (PUT
, DELETE
, etc.), you can give access to particular headers, and much more. Mozilla has an excellent introduction to what CORS can do.