秒建一個 json 轉 jsonp 的中間層伺服器
問題來源
期末的一個作業,我和同學打算建一個前後端分離的 Web 專案。他用 java 寫了一個 api server,而我則構建前端。
我們的 api 抄了別人的一套設計,但只有自己實現的介面遇到了跨域資源請求被禁止的問題。
經過一番調查,我發現別人的介面獲取的資料其實是jsonp
格式,只是文件裡讓你看起來像獲取json
一樣。
jsonp 和 json
我翻開《JSON 必知必會》發現發現其 6.3.2 小節有介紹jsonp
。
json
我就不多講了,我們看看jsonp
是怎麼一回事。
我們用jQuery
向服務發起一個ajax
請求jsonp
資料(注意dataType
欄位):
$.ajax({
method: 'GET',
url:"http://localhost:3000/login",
dataType:"jsonp",
data: {
userid: that.userid
},
success(data, status, xhr) {
console.log(data);
}
})
瀏覽器實際向伺服器發起的請求 url 是這樣的(注意callback
這個查詢引數):
http://localhost:3000/login?userid=h&callback=jsonp
從伺服器返回的引數竟然是一段javascript
程式碼:
jsonp({
"success": false,
"code": 13
});
原來,jsonp
是這麼工作的:它通過動態地向頁面插入<script>
的方式獲取資料。
我們使用的jQuery
庫的函式做好了很多工作,讓它感覺和獲取json
一樣。(js原生寫法可以看《JSON 必知必會》6.3.2)
既然知道是怎麼一會事了,我該如何補救呢?
解決辦法
1. 改 java 伺服器端程式碼
這個方法很現實,不過:
- 老實說我 java 已經不會寫了,其對於我來說是 Readonly。
- 找同學修改,不太好意思呢。
2. 做個轉換的中間層
對於我個準前端來說,還是node.js
最友好。
實現思路大致如下:
-> 獲得請求
-> 所有請求轉發 java 伺服器
-> 從 java 伺服器獲得的 json 幷包裝成 callback(json),也就是jsonp
-> 回覆
像這個樣子:
--------------- 請求JSONP --------------- 請求JSON ---------------
| |------------------>| json |------------------>| |
| 瀏覽器 | | to | | 伺服器 |
| |<------------------| jsonp |<------------------| |
--------------- 答覆JSONP --------------- 答覆JSON ---------------
原來我的想法是通過 node 的原生 api 來做,後來想起原來一直拿來做靜態 api server 的 json-server 模組,結果寥寥幾行程式碼就搞定了:
var server = require('json-server')();
var request = require('request');
var serverUrl = 'http://the.url.of.json.server';
server.get('*', function (req, res) {
request(serverUrl + req.url, function (error, response, body) {
res.jsonp(JSON.parse(response.body));
});
});
server.listen(3000);
(同學 api 實現得不太好,錯誤的引數會返回 tomcat 的 html 頁面,所以我是做了錯誤處理以防崩潰,上面程式碼簡便起見不處理了)
json-server
還有提供網頁資源的功能,如果頁面是這裡提供,那麼直接轉發json
也是可以的,不跨域了嘛。
總結
最後再囉嗦點其他東西:
- 我覺得別人的 API 是這樣設計的:當請求引數有
callback
時答覆jsonp
,沒有則是json
,這樣伺服器可以多端通用啦!這個引數取名叫callback
難道是業界通用? - 其實跨域也不是隻有
jsonp
一種辦法,還有更安全的跨域資源共享(cross-origin resource sharing,CORS)技術,也在《JSON 必知必會》6.3 裡。 - 我為什麼要寫這篇文章呢?這裡其實沒什麼技術含量,只是我網上一搜全是 Java、PHP 伺服器上的方法,那就不是很容易看明白。難道遇到這問題最多的不是前端程式設計師嗎?
相關文章
- 如何構建通用 api 中間層API
- Oracle中間的秒Oracle
- json和jsonpJSON
- json jsonp的區別JSON
- 如何構建通用儲存中間層
- json與jsonp的區別JSON
- python中的時間轉換,秒級時間戳轉string,string轉時間Python時間戳
- 說說JSON和JSONPJSON
- iOS基於中間層的路由跳轉方案iOS路由
- 一個簡單的Json轉換器JSON
- 用多層架構構建一個簡易留言本 (轉)架構
- 手寫一個jsonp實現JSON
- 利用Runtime寫一個JSON轉Model的工具JSON
- 加快apk的構建速度,如何把編譯時間從130秒降到17秒APK編譯
- JSON 與 Java 物件之間的轉化JSONJava物件
- Json,String,Map之間的轉換JSON
- 在應用程式中將OJB作為一個儲存層使用(一) (轉)
- 不改變中間層,如何玩轉 .NET 的遠端處理功能?
- 一個Vue3可使用的JSON轉excel元件VueJSONExcel元件
- 分享自己寫的一個 Python 的 JSON 轉 Model 庫PythonJSON
- 加快apk的構建速度,如何把編譯時間從130秒降到17秒(二)APK編譯
- 基於 cookie 的 node 中間層灰度流程的一些思考Cookie
- oracle 兩個時間相減得秒Oracle
- java物件與json物件間的相互轉換Java物件JSON
- Java獲取精確到秒的時間戳(轉)Java時間戳
- Json轉換(一)JSON
- 圖片預載入,圖片懶載入,和jsonp中的一個疑問JSON
- php 將秒數轉換為時間(年、天、小時、分、秒)PHP
- 用explode函式把json中用一層級資料一行轉換多行函式JSON
- Python秒轉換成時間(時分秒)Python
- [轉]:如何快速構建一個簡單的程式
- JSON:如果你願意一層一層剝開我的心,你會發現…這裡水很深——深入理解JSONJSON
- JSONP的一點筆記JSON筆記
- fastjson: json物件,json物件陣列,javabean物件,json字串之間的相互轉化ASTJSON物件陣列JavaBean字串
- 在應用程式中將OJB作為一個儲存層使用(二) (轉)
- 在應用程式中將OJB作為一個儲存層使用(三) (轉)
- 在應用程式中將OJB作為一個儲存層使用(四) (轉)
- 在應用程式中將OJB作為一個儲存層使用(六) (轉)