做前端开发,大多数情况下,都需要跟后端打交道,而最常见的方式则是通过http请求,进行通信。

在openresty中,通过http跟后端整合通信的方式又很多种,各有各的好处,可以根据情况交叉使用

1、直接proxy

这种方式最简单,也是我们最熟悉的,直接配置一个反向代理,跟nginx的用法一致

比如我们有一个后端服务,提供用户相关接口,是java写的,端口8080,为了简单起见,我直接在openresty里面配置一个server,模拟java端,通过一个简单的案例的来说明情况

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目录读取,然后返回,从这里开始就是前端开发了

为了简单起见,假设后端提供了一个登陆接口,我们这里直接用lua来实现一下就好了,检查用户名跟密码是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" then
res['ret'] = true
res['token'] = ngx.md5('admin/' .. tostring(ngx.time()))
else
res['ret'] = false
end ngx.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

这个方法主要用于发送内部请求,即请求当前server内的其他location,默认会将当前请求的参数带过去,也可以手动指定参数,GET参数通过args传递,post参数通过body传递

如:

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>

3、第三方模块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部分

openresty 前端开发进阶一之http后端的更多相关文章

  1. openresty 前端开发入门五之Mysql篇

    openresty 前端开发入门五之Mysql篇 这章主要演示怎么通过lua连接mysql,并根据用户输入的name从mysql获取数据,并返回给用户 操作mysql主要用到了lua-resty-my ...

  2. openresty 前端开发序

    还记得第一次尝试前后端分离的时候,是使用nginx + react 构建的spa应用,后端是java,主要处理业务逻辑逻辑部分,返回json数据,在nginx里面配置好html + js纯静态文件,再 ...

  3. openresty 前端开发轻量级MVC框架封装二(渲染篇)

    这一章主要介绍怎么使用模板,进行后端渲染,主要用到了lua-resty-template这个库,直接下载下来,放到lualib里面就行了,推荐第三方库,已经框架都放到lualib目录里面,lua目录放 ...

  4. openresty 前端开发入门一

    OpenResty ™ 是一个基于 Nginx 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库.第三方模块以及大多数的依赖项.用于方便地搭建能够处理超高并发.扩展性极高的动态 ...

  5. openresty 前端开发轻量级MVC框架封装一(控制器篇)

    通过前面几章,我们已经掌握了一些基本的开发知识,但是代码结构比较简单,缺乏统一的标准,模块化,也缺乏统一的异常处理,这一章我们主要来学习如何封装一个轻量级的MVC框架,规范以及简化开发,并且提供类似p ...

  6. openresty 前端开发入门六之调试篇

    大多数情况下,调试信息,都可以通过ngx.say打印出来,但是有的时候,我们希望打印调试日志,不影响到返回数据,所以系统打印到其它地方,比如日志文件,或者控制台 这里主要用到一个方法就是ngx.log ...

  7. openresty 前端开发入门四之Redis篇

    这章主要演示怎么通过lua连接redis,并根据用户输入的key从redis获取value,并返回给用户 操作redis主要用到了lua-resty-redis库,代码可以在github上找得到 而且 ...

  8. openresty 前端开发入门二

    这一章主要介绍介绍怎么获取请求参数,并且处理之后返回数据 我们知道http请求通常分为两种,分别是GET,POST,在http协议中,GET参数通常会紧跟在uri后面,而POST请求参数则包含在请求体 ...

  9. 前端开发进阶:推荐的 CSS 书写规范

    写了这么久的CSS,但大部分前端er都没有按照良好的CSS书写规范来写CSS代码,这样会影响代码的阅读体验,这里总结一个CSS书写规范.CSS书写顺序供大家参考,这些是参考了国外一些文章以及我的个人经 ...

随机推荐

  1. 案例分享:电信行业零售业务CRM架构

    最近跟一个客户讨论销售领域的移动化需求,谈到了他们的零售业务系统的整体框架,觉得很有分享的必要. 这次聊到的客户是电信行业的巨头,说的是他们的零售业务.电信公司么,卖出去的无非是设备和服务.大体的业务 ...

  2. Android 正则表达式

    1.相关知识链接 正则表达式语法   https://msdn.microsoft.com/zh-cn/library/ae5bf541(v=vs.80).aspx 正则表达式入门教程   http: ...

  3. Android 设置EditText光标Curso颜色及粗细

    在android的输入框里,如果要修改光标的颜色及粗细步骤如下两步即可搞定: 1.在资源文件drawable下新建一个光标控制color_cursor.xml <?xml version=&qu ...

  4. sublime text2 汉化

    1.下载Sublime-Text-2中文包.zip 链接:http://pan.baidu.com/s/1mgYRW9q 密码:8ks6 2.将 Sublime-Text-2中文包.zip 解压,并将 ...

  5. OOD沉思录 --- 类和对象的关系 --- 包含关系2

    4.6 尽量让类中定义的每个方法尽可能多地使用包含的对象(即数据成员) 这其实就是高内聚的翻版强调.如果每个类的情况并非如此,那很可能是这一个类表示了两个或更多的概念,记住一个类只应该表示一个概念. ...

  6. Oracle查看所有用户

    1.查看所有用户:select * from dba_users;   select * from all_users;   select * from user_users; 2.查看用户或角色系统 ...

  7. subline 快捷键

    subline 快捷键  安装 pretty css  html  后1,CTRl+ shift +H 格式化代码

  8. 第一次配置Android环境

    配置Android环境,相信很多人都做过,而且网上的资料也一大堆,我就来分享一下我配置Android的心得吧! 第一步:下载好需要的文件:Android SDK.JDK.Eclipse.ADT ps: ...

  9. ArcGis 10+Oracle发布WFS-T服务,无法更新Feature的解决方法

    现象: 前端采用Openlayers,更新Feature时服务器端返回的XML提示更新错误 原因: 参考:http://support.esri.com/en/knowledgebase/techar ...

  10. Bash Shell read file line by line and substring

    #read one file line by line for line in $(cat test1.txt); do echo $line ; done; #while read split li ...