ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

用 Sinatra 学透 HTTP 与 Web 基础:Rails Girls Web Fundamentals 教程实战

用 Sinatra 学透 HTTP 与 Web 基础:Rails Girls Web Fundamentals 教程实战 教程后端【免费下载链接】guides.railsgirls.comRails Girls Guides项目地址https://gitcode.com/gh_mirrors/gu/guides.railsgirls.com点击查看免费下载本篇技术指南源自 Rails Girls Guides 仓库中的 Web Fundamentals 教程_pages/sinatra.md以轻量级 Ruby 框架 Sinatra 为载体逐层拆解浏览器与 Web 服务器之间的 HTTP 通信机制——从 URL 结构、请求/响应模型、HTTP 动词到表单提交、参数解析、POST/Redirect/GET 重定向模式。读者将亲手构建一个咖啡清单小应用在完成每个动手练习的同时建立起对 Web 应用请求链路与 Rails 底层原理的具象认知。教程背景理解 HTTP才能理解 WebHTTP超文本传输协议用于在应用比如你在 Rails Girls 中构建的 App与浏览器之间传递信息。HTTP 通信的基础是请求/响应request/response对请求Request由浏览器发送给服务器即你的应用响应Response由服务器发回给浏览器最终呈现给用户观看。在浏览器中发起一次请求必须使用URL。URL 中包含大量关于你想请求什么信息的描述服务器据此才能返回正确的响应。教程选用 Sinatra 作为演示工具——它是一个用极少量代码创建 Ruby Web 应用的小型框架。Sinatra 与 Rails 不同二者都是帮助你编写 Web 应用的框架但 Sinatra 包含更少的特性和更少的魔法正因如此它更适合作为观察 HTTP 通信原理的显微镜。URL一次请求的地址簿一个 URL 通常包含以下组成部分协议protocol你将要用来通信的协议例如http域名domain存放你想要信息的服务器地址路径path该服务器上资源的位置参数parameters可选位于 URL 末尾、以键值对key/value pairs形式携带的附加请求信息靠近开头的//表示这次请求希望与一台服务器建立联系靠近末尾的?标志文件路径的结束、可选参数的开始。URL 揭示了你想要的资源resource但要对资源执行何种动作action则需要通过HTTP 动词HTTP verbs来指定。最常见的四种 HTTP 动词如下HTTP 动词作用GET获取fetch一个已存在的资源POST创建create一个新资源通常携带创建新资源所需的数据PUT更新update一个已存在的资源DELETE删除delete一个已存在的资源你其实早已用过这些动词在 Rails Girls 应用中启用显示、创建、编辑、删除帖子或便签功能时背后的路由正是映射到这些动词上。一次完整的请求必须同时包含URL 与 HTTP 动词。在接下来的练习中你将构建一个小的咖啡清单应用通过资源文件夹名称 HTTP 动词的组合直观观察浏览器与应用之间的通信过程。环境准备安装 Sinatra首先在终端安装 gemgem install sinatra gem install sinatra-contrib其中sinatra是框架本体sinatra-contrib提供sinatra/reloader等扩展组件稍后用于开发时热重载。Ruby 3.x 兼容性提示仓库中的配套投票应用教程_pages/sinatra-app-tutorial.md在安装步骤中额外执行了gem install sinatra webrick。这是因为从 Ruby 3.0 起webrickRuby 内置 Web 服务器不再是默认随附 gem如果启动ruby app.rb时报缺少webrick相关错误请补装它即可。第一个路由Hello World新建一个文件app.rb在文本编辑器中粘贴如下内容require sinatra require sinatra/reloader get / do Hello world! end回到终端运行这段代码ruby app.rb然后在浏览器访问 http://localhost:4567——你现在看到的信息就是一次GET 请求的响应当你输入http://localhost:4567时实际是向你的 Sinatra 服务器发送了一个GET请求浏览器里显示的内容正是 Sinatra 服务器返回的响应。代码中的/指定的是根路径root URL但你可以按同样的语法创建任意路径名页面数量不限、内容随你定义例如get /page-name do This is text on the page end需要停止应用时在命令行按CtrlC和停 Rails 应用的方式一样。不过在本教程中你不需要每次改动后都停止并重启——因为sinatra/reloader会在你保存app.rb时自动重载代码。用 HTML 表单发送 GET 参数要让应用列出咖啡首先需要一个 HTML 表单把要哪种咖啡、多少钱发送给服务器。这意味着向 Sinatra 服务器发送一次携带信息的请求——在 HTML 中实现向服务器发送信息的标准工具就是表单。把前面的get /替换为以下内容get / do html body form action/ methodget What: input namewhat Cost: input namecost button typesubmitadd coffee/button /form !-- coffees go here -- /body /html end为简单起见这个表单把信息发送到同一个 URL/。刷新浏览器你应该能看到刚创建的表单。现在观察浏览器提交表单时到底向服务器发送了什么在表单里输入一些文字点击add coffee按钮然后查看终端里的 Sinatra 日志你应该能看到类似这样的一行GET /?whatflatwhitecost3.50 HTTP/1.1教练提示coach这里的参数名what、cost正是表单中input的name属性而?之后的keyvalue对用连接表示空格URL 编码。这正是原文档中建议教练向学员解释的两个关键点。用 Web Inspector 观察请求头在浏览器中打开开发者工具大多数浏览器可通过在页面上右键选择 Inspect Element进入教程推荐使用 Chrome此时请切换到Network标签页。刷新页面后点击 Web Inspector 中的localhost那一行在 Headers 标签页点击 view source你会看到类似下面的内容GET / HTTP/1.1 Host: localhost:4567 Connection: keep-alive Cache-Control: max-age0 Accept: text/html,application/xhtmlxml,application/xml;q0.9,image/webp,*/*;q0.8 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.70 Safari/537.36 Accept-Encoding: gzip,deflate,sdch Accept-Language: en-US,en;q0.8教练提示coach这些行就是HTTP 请求头request headers——浏览器在每次请求时附带的元信息例如Host声明目标主机、User-Agent声明浏览器身份、Accept声明可接受的内容类型等。最值得注意的第一行它同时展示了本次请求使用的HTTP 动词和它调用的URL。关于 WEBrick 的说明如果 Sinatra 提示使用了 WEBrickRuby 内置 Web 服务器的备份服务那么你每次刷新可能会看到多个GET请求。实际上只有一次请求是真实发出的其余可以安全忽略。用全局变量保存状态表单正在把咖啡信息发送给应用但应用还没有处理它们。我们应该在数据到达服务器后把它保存下来。为了简单起见教程把咖啡数据存放在一个全局变量global variable中使它能在多次请求之间保持可用——这可以看作 Rails 中Model 层的一个极度简化的版本。在app.rb中的某处按惯例应放在文件顶部、require行之下添加$coffees []这行代码会在应用首次启动时创建一个空数组。注意这个全局变量寿命很短——每次服务器重启都会重置为空数组。由于我们启用了 Sinatra 的 reloader这意味着每次保存app.rb文件都会触发重置。不过对于本教程的目的而言这完全够用。从 params 接收数据存储咖啡现在当请求到达时你需要把数据写进$coffees数组。回想刚才的提交过程你填好表单并点击提交按钮时信息被拼接到 URL 末尾?之后发送回服务器。Sinatra 会从 URL 末尾抓取这段信息并封装成一个名为params的 Hash 暴露给路由代码。例如提交whatflatwhitecost3.50之后params的内容等价于params { what flat white, cost 3.50 }Hash 的 key 与表单中input的name属性一一对应教程原稿中的示例写法在 Ruby 语法上不够严谨实际使用或符号键构造 Hash。原文档也提示若卡住可查阅 Ruby 的 Hash 与 Array 文档自行尝试。接下来需要编写代码把参数从params中取出并加入$coffees变量。动手之前先把表单中的!-- coffees go here --占位注释替换为#{ $coffees.inspect }这样浏览器里的 HTML 会直接显示$coffees变量的内容方便你确认咖啡是否真的被添加进了数组即代码是否正常工作。提示$coffees是一个数组。如果卡住了可以去查 Ruby 的 Array 文档找到如何向数组添加信息的方法——例如追加运算符$coffees params。如果 params 存储正确你每次刷新浏览器都能看到一个新 Hash 被添加进$coffees数组。重构把 HTML 抽成 template 方法get代码里那一大坨 HTML 字符串让应用逻辑变得难以阅读让我们把它搬进一个独立方法。把 HTML 表单部分从get代码中剪切出来粘贴进一个名为template的方法所有代码仍保留在同一个文件里def template # put your HTML form string here end然后用一次简单的方法调用替换get代码中的表单get / do $coffees params template end这样一来应用的主干逻辑一眼可辨把参数存入数组然后渲染模板。把 HTML 抽成方法还带来一个额外好处——以后可以方便地复用这个表单。从 GET 走向 POSTGET 不该产生副作用细心的读者会发现在存储咖啡一节每次刷新浏览器应用都会把信息重复加进$coffees全局变量。原因很简单——我们的get代码每次被请求时都在存储 URL 中的 params。这里恰好引出一个重要的 HTTP 原则GET请求不应该执行向应用添加信息这类操作。虽然像本例这样也能工作但太容易引发非预期的副作用。这种情况下更合适的是POST请求GET请求是在获取资源POST请求是在创建资源。基于这个认识我们把表单的 method 改为POST在表单中找到指定method为get的位置把它改成post刷新浏览器提交一杯新咖啡。糟糕如果你还没遇到过那么恭喜你——欢迎来到 Sinatra 可爱的错误页面。页面底部的提示信息大致是Try this: post / do Hello World end这是 Sinatra 在告诉你你请求的路由不存在。你也许知道它对应的 HTTP 错误号——404page not found。添加 POST 路由现在把post代码写进 Sinatra不要删掉已有的get从 Sinatra 的 404 页面中把那段 Hello world 的post代码复制过来放在get之后提示不要从本页上方复制——页面使用了智能引号会破坏你的代码把 Hello world 替换为对template方法的调用提示不要移除get代码里对template的调用把存储咖啡参数的代码行移动到post代码里确保它位于template调用之上。现在提交一杯咖啡后刷新页面浏览器会弹出一个警告需要重新提交表单才能加载页面你在网上填表时可能见过这个警告。它的存在促使我们思考刷新的后果从而避免无意中把同一杯咖啡重复添加多次。原因正是前面讲过的原则刷新GET页面只是反复请求查看同一个页面通常没问题但刷新POST页面意味着重新发送POST请求每次刷新都可能创建一个新资源所以浏览器会在放行前给出警告。POST/Redirect/GET用 HTTP 303 消除重复提交要绕开表单重复提交问题可以在收到POST的响应后立刻让浏览器加载另一个页面。这要用到一种特殊的 HTTP 响应——重定向redirect。在 Sinatra 中把post代码里对template的调用替换为redirect /这会向浏览器返回一个特殊的重定向响应HTTP 303并在响应头中携带Location头指明浏览器下一步该去哪里HTTP/1.1 303 See Other … Location: http://localhost:4567/要亲眼看这个过程在 Chrome 的 Web InspectorNetwork 标签页中向应用提交一杯咖啡你会看到如下时序第一行浏览器通过POST方法提交表单它收到的响应是HTTP 303包含Location头浏览器随即对那个位置对应根 URL/发出一次GET请求并渲染这次GET得到的响应——也就是我们的 HTML 模板。这套流程就是著名的POST/Redirect/GETPRG模式。现在你可以放心地随意刷新页面——刷新发出的都是GET请求不再是POST浏览器展示该页面时也无需再提交表单。教程到这里即告结束。进阶把咖啡列表渲染成真正的 HTML教程末尾的 Additional Guides 指向了配套文档_pages/sinatra-html.mdCoffee List Display。用.inspect输出数组内容适合调试但不适合上线一来很难对输出做样式化二来可读性差。进阶练习的目标是把咖啡列表包装进真正的 HTML 标签。首先新建一个方法用于返回包裹在 HTML 标签中的咖啡列表命名为coffees_htmldef coffees_html # Build HTML here end然后在template方法中把#{ $coffees.inspect }那一行替换为对新方法的调用#{ coffees_html }最终期望的输出效果类似divFlat White $3.50/div br divCappuccino $2.50/div提示$coffees是一个Hash 的数组。实现思路是遍历$coffees把每个 Hash 转成一个用div包裹的 HTML 字符串再用br把它们连接起来并确保方法最终返回一个字符串。若卡住可对照原教程提供的参考答案片段自查教程每步都附有完整参考代码出错时可随时对照。教程背后的仓库支撑coach 提示与站点结构这份教程并非孤立文档它生长在 Rails Girls Guides 仓库的 Jekyll 站点结构中教练提示标签文中多处{% coach %}...{% endcoach %}提示块由仓库自定义 Liquid 标签渲染。实现位于 _plugins/coach.rbCoachTag继承Liquid::Block把标签内容按 Markdown 转换后包裹进带coach-notice样式的div统一呈现为Help from the coach提示卡。仓库 README.md 也专门说明了这一约定的用法以保证所有指南中的教练提示视觉一致、易于辨认。页面布局该教程使用layout: guide见文件头部 front matter对应 _layouts/guide.md它继承default布局并将正文包裹在article classguide中文末附 View more guides! 引导。站点配置_config.yml 设置permalink: pretty与markdown: kramdown并将_pages目录纳入构建本站的 Gemfile 依赖jekyll、jekyll-redirect-from与webrick。同类教程对照_pages/sinatra-app-tutorial.md是同一主题的姊妹篇——用 Sinatra 构建投票应用Suffragist涵盖erb :index模板渲染、title实例变量向视图传值、YAML::Store持久化投票结果等进阶内容可作为本篇教程之后继续深造的路径。小结通过本教程你亲手走完了一条完整的 Web 请求链路拆解URL的协议、域名、路径与参数认识?与//的语义掌握GET / POST / PUT / DELETE四种 HTTP 动词各自承担的职责用 HTML 表单发送数据并从 Sinatra 的paramsHash 中取回参数借助全局变量模拟简单的模型层存储亲历GET 的副作用陷阱 → POST → 404 → POST/Redirect/GET303的完整演进理解浏览器重新提交表单警告的由来与对策。这些概念与你在 Rails Girls 中构建的应用一脉相承当你在 Rails 中定义resources路由、提交表单或处理重定向时底层运行的正是同样的 HTTP 机制。继续沿着_pages/sinatra-html.md把咖啡列表渲染成规范的 HTML或转入_pages/sinatra-app-tutorial.md用 ERB 模板与 YAML 持久化构建一个完整的投票应用你的 Web 基本功将进一步成型。赞分享教程后端【免费下载链接】guides.railsgirls.comRails Girls Guides项目地址https://gitcode.com/gh_mirrors/gu/guides.railsgirls.com点击查看免费下载相关推荐用 Sinatra 从零构建投票应用Rails Girls Suffragist 实战教程用 Sinatra 从零构建投票应用Rails Girls Suffragist 实战教程 导读 本教程是 Rails Girls Guides https:教程后端Rails Girls GuidesPWA开发渐进式Web应用实战Rails Girls GuidesPWA开发渐进式Web应用实战 你是否希望自己开发的Rails应用能像原生App一样离线运行、接收推送通知并拥有流畅的用户教程后端PCG-CPP完全指南从基础使用到高级配置的完整教程PCG CPP完全指南从基础使用到高级配置的完整教程 PCG CPP是一款高效、统计性能优异的随机数生成库为C开发者提供了丰富的随机数生成解决方案。本教上一篇mise token gitlab 命令详解诊断与调试 GitLab 认证 Token下一篇Sim 前端样式规范实战指南从 Tailwind 工具类到设计 Token 体系创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表