那么,是 JSONP 还是 CORS?

我的 WebAPI 部署在 内部网环境中,这意味着 保安不是我关心的问题。

似乎 CORS 对于客户来说是 友好多了,对于客户来说是 更容易实施

还有什么我没注意到的吗?

47387 次浏览

This is a pretty broad question, and could warrant a wiki unto itself. There is also quite a bit on google regarding the two, but I think I can hit a few key points.

  • If you need a read-only ajax interface to your servers and you need to support IE<=9, Opera<12, or Firefox<3.5 or various other older or obscure browsers, CORS is out, use JSONP. IE8 and IE9 sorta support CORS but have problems, see the link in the first comment below.
  • On the other hand, if your web API is read/write (e.g. full REST or just POST/GET) instead of just read (i.e. GET), JSONP is out. Use CORS. JSONP is inherently read-only.

If neither of these are a concern, I would just go with whatever is easiest or most familiar to you. If its a tossup, try CORS, since it is the more "modern" solution and JSONP is more of a hack, turning data into scripts to bypass cross-domain restrictions. CORS does however, typically require more server-side configuration.

If you're using jQuery, I'm not sure where you're coming up with the idea that CORS is "much more friendly to the client and easier to implement." See https://gist.github.com/3131951 . jQuery abstracts the details of JsonP, and CORS can actually be somewhat tricky to implment on your server-side depending on what technology you're using.

I recently developed a web app, using jquery and backbone.js, which reads from various cross-domain web services that we control, and ended up using Json-P instead of CORS because we need to support IE7 and it was a bit simpler on the server side (we run Django w/ DjangoRestFramework), and virtually the same with jquery on the client side.

You are pretty spot on. If you don't have to support legacy browsers (ones released 6+ years ago) I would definitely go with CORS.

CORS is easier to implement, in that if your API doesn't already support JSONP or CORS it's easier to just add a few static headers than modifying the body of responses.

Also it's easier to cache requests using CORS. Each JSONP request needs to be dynamic even with memcached content.

JSONP is still a script tag, so no matter what it will cause some level of synchronous behavior. CORS will not.

JSONP can only be a GET. And as with CORS you can do use any method.

Last but not least, if you're using jQuery v1.x, consider that error and complete (or better fail and always) handlers are still not called for JSONP requests in some common situations (e.g. network errors). Sure there are workarounds (timeout setting, jQuery-JSONP plugin), but I find CORS less annoying, expecially when cross-domain requests are only coming from mobile devices (i.e. hybrid apps) so you don't need support for unlucky browsers.

Our Web API was not working on Safari (iOS 9.1) with Windows Authentication. It was working with Safari + iOS 8.4. When we changed to JSONP Safari started working again. Check this link for more information.

According to Spring Documentation, JSONP is a hack and not a proper solution of Cross Origin Resource Sharing. So if security is not your concern then simply check your domain origin on your server and add Access-Control-Allow-Origin Response header.