在openresty中,經過http跟後端整合通訊的方式又不少種,各有各的好處,能夠根據狀況交叉使用javascript
這種方式最簡單,也是咱們最熟悉的,直接配置一個反向代理,跟nginx的用法一致css
好比咱們有一個後端服務,提供用戶相關接口,是java寫的,端口8080,爲了簡單起見,我直接在openresty裏面配置一個server,模擬java端,經過一個簡單的案例的來講明狀況html
nginx.conf前端
worker_processes 1; error_log logs/error.log; events { worker_connections 1024; } http { lua_package_path "/Users/john/opensource/openresty-web-dev/demo7/lua/?.lua;/usr/local/openresty/lualib/?.lua"; server { listen 80; server_name localhost; lua_code_cache off; location / { root html; index index.html; } location ~ ^/user { proxy_pass http://127.0.0.1:8080; } } # 這個只是模擬後端 server { listen 8080; server_name localhost; lua_code_cache off; location ~ /user/(.+) { default_type text/html; content_by_lua_file lua/$1.lua; } } }
上面配置了兩個location,將全部以/user開頭的請求都轉到後端的8080服務器,其餘的則是靜態頁面,直接從html目錄讀取,而後返回,從這裏開始就是前端開發了java
爲了簡單起見,假設後端提供了一個登錄接口,咱們這裏直接用lua來實現一下就行了,檢查用戶名跟密碼是admin,就返回成功,不然返回失敗react
lua/login.luajquery
local req = require "req" local cjson = require "cjson" local args = req.getArgs() local username = args['username'] local password = args['password'] local res = {} if username == "admin" and password == "admin" then res['ret'] = true res['token'] = ngx.md5('admin/' .. tostring(ngx.time())) else res['ret'] = false end ngx.say(cjson.encode(res))
index.htmlnginx
<html> <head> <meta charset="UTF-8"> <title>Login Page</title> </head> <body> UserName: <input type="text" id="username" value="admin"> Password: <input type="password" id="password" value="admin"> <a href="javascript:void(0)" onclick="login()">Login</a> <script src="//cdn.bootcss.com/jquery/2.2.4/jquery.min.js"></script> <script> function login() { var username = $('#username').val(); var password = $('#password').val(); $.post('/user/login', {username: username, password: password}, function(res){ console.log(res) var msg = res.ret ? "登陸成功" : "登陸失敗" alert(msg) }, 'json') } </script> </body> </html>
二、使用ngx.location.captruegit
這個方法主要用於發送內部請求,即請求當前server內的其餘location,默認會將當前請求的參數帶過去,也能夠手動指定參數,GET參數經過args傳遞,post參數經過body傳遞github
如:
local req = require "req"
local args = req.getArgs()
GET 調用
local res = ngx.location.capture('/user/login', {
method = ngx.HTTP_GET, args = args,
});
POST 調用
local res = ngx.location.capture('/user/login', {
method = ngx.HTTP_POST, body = ngx.encode_args(args),
});
如今咱們本身寫一個lua來調用後臺接口實現登錄,而後對請求作一點處理,實現一些額外的邏輯,好比在原來的參數上面加上一個from字段
lua/local-login.lua
local req = require "req" local cjson = require "cjson" local args = req.getArgs() -- GET local res = ngx.location.capture('/user/login', {method = ngx.HTTP_GET, args = args}) -- POST -- local res = ngx.location.capture('/user/login', {method = ngx.HTTP_POST, body = ngx.encode_args(args)}) -- print(res.status) -- 狀態碼 if res.status == 200 then local ret = cjson.decode(res.body) ret['from'] = 'local' ngx.say(cjson.encode(ret)) else print(res.body) ngx.say('{"ret": false, "from": "local"}') end
index.html 也須要改一下,多加一個按鈕,調用本地登錄接口
<html> <head> <meta charset="UTF-8"> <title>Login Page</title> </head> <body> UserName: <input type="text" id="username" value="admin"> Password: <input type="password" id="password" value="admin"> <a href="javascript:void(0)" onclick="login()">Login</a> <a href="javascript:void(0)" onclick="local_login()">Local Login</a> <script src="//cdn.bootcss.com/jquery/2.2.4/jquery.min.js"></script> <script> function login() { var username = $('#username').val(); var password = $('#password').val(); $.post('/user/login', {username: username, password: password}, function(res){ console.log(res) var msg = res.ret ? "登陸成功" : "登陸失敗" alert(msg) }, 'json') } function local_login() { var username = $('#username').val(); var password = $('#password').val(); $.post('/lua/local-login', {username: username, password: password}, function(res){ console.log(res) var msg = res.ret ? "本地登陸成功" : "本地登陸失敗" alert(msg) }, 'json') } </script> </body> </html>
三、第三方模塊lua-resty-http
這種方式跟上面那種不一樣的地方是調用的時候,不會帶上本地請求的請求頭、cookie、以及請求參數,不過這也使得請求更純粹,不會帶上那些不必的東西,減小數據傳輸
最後local-login.lua 變成以下
local req = require "req" local cjson = require "cjson" local http = require "resty.http" local args = req.getArgs() -- GET -- local res = ngx.location.capture('/user/login', {method = ngx.HTTP_GET, args = args}) -- POST -- local res = ngx.location.capture('/user/login', {method = ngx.HTTP_POST, body = ngx.encode_args(args)}) -- http local httpc = http.new() local res = httpc:request_uri("http://127.0.0.1:8080/user/login", { method = "POST", body = ngx.encode_args(args), headers = { ["Accept"] = "application/json", ["Accept-Encoding"] = "utf-8", ["Cookie"] = ngx.req.get_headers()['Cookie'], ["Content-Type"] = "application/x-www-form-urlencoded", } }) httpc:set_keepalive(60) print(res.status) -- 狀態碼 if res.status == 200 then local ret = cjson.decode(res.body) ret['from'] = 'local' ngx.say(cjson.encode(ret)) else print(res.body) ngx.say('{"ret": false, "from": "local"}') end
到此,基本上已經能經過openresty,作一些先後端的交互了,下次介紹怎麼使用openresty模板渲染,以及搭配react開發前端。
示例代碼 參見demo7部分