[UI/API] 讓你的requests CORS 起來...
這都是乃衣服, 也許只有前端才會問生層次問題, 是和UI同一個server 嗎? (前端後端沒分離), 還是不同(前端後端分離)?
如果答案就這麼顯然易見的話, 這個文章就沒有必要看了.
言歸正傳, 如何目前前端發送API 有兩種:
- JSONP
- CORS
JSONP, 可能有年頭的前端開發都聽過, 做過, 但是會發現, 這根本就是23寫法, 只有GET, 沒有別的HTTP Methods. 另外這都是2017年了, 還用這個, 會遭鄙視的....
首先介紹點CORS的背景資料,
UI會給API發送的request header裡面添加
Access-Control-Request-Headers:content-typeAccess-Control-Request-Method:GET Access-Control-Request-Method:POST
就和一般的AJAX差不多, 但是呢, 在CORS裡面呢, 它會第一次發送一個 OPTIONS 的 HTTP Method, 也就是 (pre-flight).
在Server 返回 status 200以後, 再次發送真正的request, 比如說payload, request type.
如圖:
我們再讀一讀 Mozilla 的Guideline: Mozilla Access_control_CORS
接下我們來看一些代碼:
前端 (jQuery Ajax 配置)
$.ajaxSetup({ type: "POST", data: {}, dataType: json, xhrFields: { withCredentials: true }, crossDomain: true});
後端 (Express - Nodejs)
app.use(function(req, res, next) { res.header(Access-Control-Allow-Origin, req.get(Origin) || *); res.header(Access-Control-Allow-Credentials, true); res.header(Access-Control-Allow-Methods, GET,HEAD,PUT,PATCH,POST,DELETE); res.header(Access-Control-Expose-Headers, Content-Length); res.header(Access-Control-Allow-Headers, Accept, Authorization, Content-Type, X-Requested-With, Range); if (req.method === OPTIONS) { return res.send(200); } else { return next(); }});
這個是我們自己的實現, 但是社區已經有幾個完善的庫了, 就不要再造輪子了.
- Express CORS
- Flask CORS
Flask CORS 例子
from flask import Flask, jsonifyfrom flask_cors import CORS, cross_originapp = Flask(__name__)CORS(app, support_credentials=True)@app.route("/login")@cross_origin(supports_credentials=True)def login(): return jsonify({success: ok})if __name__ == "__main__": app.run(host=local-host, port=8000, debug=True)
Reference
- How to enable CORS on express.js 4.x on all files
- How to: enable CORS in express.js
如果你喜歡, 請給個贊吧.
推薦閱讀:
※前後端分離的情況下, 跨域問題有沒有好的解決方案?
※由Request Method:OPTIONS初窺CORS
※iframe 完全跨域,就是不同域名不同伺服器之間的跨域?JS 如何做到
※來一發跨域解決方式---nginx
※跨域的那些事兒