openresty 前端开发进阶一之http后端
2019獨(dú)角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>
做前端開發(fā),大多數(shù)情況下,都需要跟后端打交道,而最常見的方式則是通過http請(qǐng)求,進(jìn)行通信。
在openresty中,通過http跟后端整合通信的方式又很多種,各有各的好處,可以根據(jù)情況交叉使用
1、直接proxy
這種方式最簡(jiǎn)單,也是我們最熟悉的,直接配置一個(gè)反向代理,跟nginx的用法一致
比如我們有一個(gè)后端服務(wù),提供用戶相關(guān)接口,是java寫的,端口8080,為了簡(jiǎn)單起見,我直接在openresty里面配置一個(gè)server,模擬java端,通過一個(gè)簡(jiǎn)單的案例的來說明情況
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;}}# 這個(gè)只是模擬后端server {listen 8080;server_name localhost;lua_code_cache off;location ~ /user/(.+) {default_type text/html; content_by_lua_file lua/$1.lua;}}}上面配置了兩個(gè)location,將所有以/user開頭的請(qǐng)求都轉(zhuǎn)到后端的8080服務(wù)器,其他的則是靜態(tài)頁面,直接從html目錄讀取,然后返回,從這里開始就是前端開發(fā)了
為了簡(jiǎn)單起見,假設(shè)后端提供了一個(gè)登陸接口,我們這里直接用lua來實(shí)現(xiàn)一下就好了,檢查用戶名跟密碼是admin,就返回成功,否則返回失敗
lua/login.lua
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" thenres['ret'] = trueres['token'] = ngx.md5('admin/' .. tostring(ngx.time())) elseres['ret'] = false endngx.say(cjson.encode(res))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><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>2、使用ngx.location.captrue
這個(gè)方法主要用于發(fā)送內(nèi)部請(qǐng)求,即請(qǐng)求當(dāng)前server內(nèi)的其他location,默認(rèn)會(huì)將當(dāng)前請(qǐng)求的參數(shù)帶過去,也可以手動(dòng)指定參數(shù),GET參數(shù)通過args傳遞,post參數(shù)通過body傳遞
如:
local req = require "req" local args = req.getArgs()
GET 調(diào)用
local res = ngx.location.capture('/user/login', { method = ngx.HTTP_GET, args = args, });
POST 調(diào)用
local res = ngx.location.capture('/user/login', { method = ngx.HTTP_POST, body = ngx.encode_args(args), });
現(xiàn)在我們自己寫一個(gè)lua來調(diào)用后臺(tái)接口實(shí)現(xiàn)登陸,然后對(duì)請(qǐng)求做一點(diǎn)處理,實(shí)現(xiàn)一些額外的邏輯,比如在原來的參數(shù)上面加上一個(gè)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) -- 狀態(tài)碼if res.status == 200 thenlocal ret = cjson.decode(res.body)ret['from'] = 'local'ngx.say(cjson.encode(ret)) elseprint(res.body)ngx.say('{"ret": false, "from": "local"}') endindex.html 也需要改一下,多加一個(gè)按鈕,調(diào)用本地登陸接口
<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>3、第三方模塊lua-resty-http
這種方式跟上面那種不同的地方是調(diào)用的時(shí)候,不會(huì)帶上本地請(qǐng)求的請(qǐng)求頭、cookie、以及請(qǐng)求參數(shù),不過這也使得請(qǐng)求更純粹,不會(huì)帶上那些沒必要的東西,減少數(shù)據(jù)傳輸
最后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) -- 狀態(tài)碼if res.status == 200 thenlocal ret = cjson.decode(res.body)ret['from'] = 'local'ngx.say(cjson.encode(ret)) elseprint(res.body)ngx.say('{"ret": false, "from": "local"}') end到此,基本上已經(jīng)能通過openresty,做一些前后端的交互了,下次介紹怎么使用openresty模板渲染,以及搭配react開發(fā)前端。
示例代碼 參見demo7部分
轉(zhuǎn)載于:https://my.oschina.net/362228416/blog/820754
總結(jié)
以上是生活随笔為你收集整理的openresty 前端开发进阶一之http后端的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python 抓包基于pypcap
- 下一篇: 这周,我们作前端,实现统一的过滤搜索