JSONP 就是个 dirty hack ,吃枣药丸,能不碰就不碰。不服来辩!
即将接手一个前端项目。
这项目之前是用 Rails + Angular1 做的,现在我们打算把 Rails 干掉,所有数据都让前端直接从 api.example.com 取。
后端 api.example.com 一定是我们自己 serve ,但前端的话:
之前的思路是,前端判断一下其所处的环境是否支持 CORS ,不行的话用 JSONP 当做 fallback 。至于 GET 以外的请求,这边用 JSONP 模拟了一套实现,看起来相当完善,前后端都有支持。并且我们的请求都很小,似乎不用考虑 413 的问题。
而现在我个人的想法是,无论部署在哪,都让跑这个项目的那个 NGINX 做一次 proxy_pass ,反代到 api.example.com (对应 1 ),或是反代到我们私有网络跑 api 的那台机器上(对应 2 )。这样的优点至少有:
缺点:
总之在我印象中,JSONP 这玩意就是落后于时代(亦或是超前于时代)的一个 hack 。以前、现在、未来都未曾、没有、不会出现在 W3C 或是 RFC 标准中,应该被抵制才对。
我目前还没有说服团队成员放弃 JSONP ,尤其是用 JSONP 模拟实现了一整套非 GET 请求的前辈。
请各位 dalao 赐教。
1
nfroot 2017-04-04 20:28:39 +08:00
放弃没问题啊。
少数赞成多数好不好 0 0 |
2
imswing 2017-04-04 20:30:19 +08:00 via Android 1
origin allows *
|
3
gdtv 2017-04-04 20:30:45 +08:00
存在却合理,既然有简单的方法解决问题(虽然这个方法不标准),为何还要用复杂的方法呢(你说的 proxy_pass 的方法我觉得比 jsonp 复杂、麻烦很多很多)?
|
4
eric6356 OP @imswing
CORS 会有一些坑,比如某些企业防火墙会屏蔽 OPTIONS 请求。这我们希望尽量避免,或者至少有 fallback 。 |
5
eric6356 OP @gdtv 也就 nginx 加一行配置?
相反 jsonp 的话,因为我很可能要完全重写这个项目,所以我需要按照目前这个并不标准的方案重新实现 JSONP 模拟非 GET 请求。当然写得好的话可能也就几十行代码,或许也是一种锻炼。 |
6
nfroot 2017-04-04 21:04:43 +08:00
“之前的思路是,前端判断一下其所处的环境是否支持 CORS ,不行的话用 JSONP 当做 fallback ”
楼主请问一下,你有更好的办法么 |
7
eric6356 OP @nfroot 我说了用 NGINX 做 proxy_pass ,当然如果如果把解决方式限定在浏览器端的话的话我也就没有更好的办法了。
我是认为反代一下之后,前后端的代码都可以更简单。 |
8
des 2017-04-04 21:31:43 +08:00 via Android
iframe 嵌入,然后用 postMessage 去获取怎么样?
刚刚想到的 |
9
eric6356 OP @des 能详细说一下吗?
是不是需要让 api.example.com 的某个接口返回某个 html ,其中有个 script 从 api 取数据,并且给 window 注册 message 事件并且在响应函数里调用 event.source.postMessage 发数据回来。 听起来麻烦得很,而且让 api 返回 html 页面真的好么? |
11
SoloCompany 2017-04-04 22:01:25 +08:00 via iPhone
标题党
你说的“技术”有哪一样是在 2016 才出现的?👎 |
12
jianyunet 2017-04-04 22:12:27 +08:00
这种情况很常见,我的选择方式通常是,如果那个 jsonp 的模拟是开源项目而且比较健康的话,就可以用,如果是需要自己造轮子的话就尽量避免
|
13
otakustay 2017-04-04 22:38:36 +08:00
我不太理解 jsonp 这种几乎没有副作用的东西为什么就是能不碰就不碰了,不碰对你来说到底有什么好处了……
另外用 nginx 做反代最大的问题难道不是丢 cookie 么? |
14
undeflife 2017-04-04 22:50:56 +08:00
也许是我没看明白,你这场景有点混乱,而场景都还没确定,先揪这么个细节是不是太早期?
>>这项目之前是用 Rails + Angular1 做的,现在我们打算把 Rails 干掉,所有数据都让前端直接从 api.example.com 取。 那你们另外有后端咯 那这个 rails 的作用是啥 - -# >>可能部署 NGINX 到各个客户服的务器上 你们的前端代码还需要部署到客户内网 客户机还可能是纯内网环境? >>本来前端所有的文件可以都交给 CDN ,现在则必须要一台服务器了 客户机有纯内网环境了,前端文件怎么能全部交给 cdn? 不是还是至少需要个能外网的机器反代吗?既然反代 server 是必要的,多加一个 api 的反代有什么问题? |
15
eric6356 OP 不碰的理由:
1. 不符合任何标准,应该抵制(个人感情因素) 2. 你也说了「几乎」没有副作用 丢 cookie 我确实没有考虑过,感谢指出。 不过一个 RESTful 的 API ,真的需要 cookie 吗? |
17
otakustay 2017-04-04 22:57:11 +08:00 2
我承认如果 cors 完全可用的情况下 jsonp 并不合适,但问题就在 cors 并不完全可用,而且同样会有一定的负面影响,比如你用非 GET 的请求就会用 preflight OPTIONS request 浪费时间,你用反向代理就给自己的服务增加压力(你想想日 PV 有 3000W 的时候你什么感觉)
这样比起来, jsonp 的副作用比 cors 小多了啊,一个函数封装以后就完全无感知了, jsonp 真正的缺点是全 GET 在安全性上守不住 |
18
eric6356 OP @undeflife 首先感谢仔细看了这个帖子
1. 之前一些数据是靠 Rails 查库的,另一些是 JSONP 。 2. 一个应用可以卖给很多客户。卖给谁,怎么卖,现在应用没有开发完,自然是不确定的了咯。 3. 抱歉这里确实没写清楚,我在目前考虑各种场景,企图用一个方案满足所有需求。 而且你说的很对,场景没定的话很多考虑都是多余的。 |
19
eric6356 OP @otakustay 其实我并不太明白反代到底会有多大的额外开销。
画了张图 A 和 B 是 example.com 自己 serve , C 和 D 是让客户 serve 。 那么 A 和 B 相比,以及 C 和 D 相比,我们 example 这一侧的其实并没有什么区别吧? |
21
k9982874 2017-04-05 00:05:55 +08:00 via iPad 1
我支持 pass_proxy 的解决方案,我司正在开展的项目和你的项目差不多情况。
sever 只提供 API 的情境下不需要考虑用户 cookie 。 另外当用户到达反代服务器承受不了的情况下,业务服务器早挂了。 用户到达那个数量级应该有大把的资金去增加服务器资源。 |
22
sagaxu 2017-04-05 00:24:45 +08:00 via Android 1
@eric6356 这种防火墙后面,一堆 APP 都会受影响无法工作,所以不用考虑这种情况。而且 ssl 加密后,防火墙根本不知道传输的内容,一个四核 CPU ,可以轻松承受几千万 pv 的 https 转发工作。
更多需要考虑的,其实是 IE8 和 IE9 的兼容性问题。在初期,设计上不能轻易放弃 fallback 的能力。 |
25
eric6356 OP |
26
changwei 2017-04-05 08:29:26 +08:00 via Android 1
@otakustay cros 同样也可以 get , jsonp 的安全问题在于提供 jsonp 数据源的服务器如果被黑或者数据源提供商自己想做一些不可描述的事情,将会影响到使用它的网站,尤其是 jsonp 的提供商如果被黑产控制,增加菠菜暗链可能还会影响 seo 。
|