chromeos_我如何使用Go以及在ChromeOS上构建网络服务器

chromeos

by Peter Gleeson

彼得·格里森(Peter Gleeson)

我如何使用Go以及在ChromeOS上构建网络服务器 (How I built a web server using Go — and on ChromeOS)

Linux→ChromeOS→Android→Linux仿真器 (Linux →ChromeOS →Android →Linux Emulator)

“Why on earth did you get a Chromebook for web development?” is a question I’m occasionally asked. People don’t seem to believe I’m able to teach myself full-stack web development on a machine marketed for its simplicity and ease-of-use.

“为什么您会获得用于网络开发的Chromebook?” 是我偶尔被问到的一个问题。 人们似乎不相信我能够在市售的机器上以简单易用的方式自学全栈Web开发。

I’ll admit that when I bought the thing back before Christmas, I didn’t expect any miracles from it. As long as it came with a text editor and an internet browser, I saw it as a cheap, portable way of learning the basics of front-end web development and watching YouTube on the go. I was also sold on the whole ‘cloud computing’ concept (that stuff’s the future).

我承认,当我在圣诞节前买回东西时,没想到会有任何奇迹。 只要它带有文本编辑器和Internet浏览器,我就将其视为学习前端Web开发基础知识和随时随地观看YouTube的一种廉价,可移植的方式。 我也被整个“云计算”概念所吸引(这就是未来 )。

As it turns out, I’ve been pleasantly surprised by just how capable the little machine is. It boots up ridiculously fast, has a great battery life, and with the help of the omnipresent ‘cloud’, does pretty much most things you’d expect from any other machine. Plus, the model I chose comes with a touchscreen that folds right over into a variety of yoga positions to give you a tablet or a ‘tent’, or any other configuration you like, which if anything, looks cool.

事实证明,这台小型机器的功能是如此令人惊讶。 它的启动速度非常快,具有出色的电池寿命,并且在无所不在的“云”的帮助下,几乎可以完成您期望从其他任何机器上获得的大部分功能。 另外,我选择的型号带有触摸屏,该触摸屏可以折叠成各种瑜伽姿势,为您提供平板电脑或“帐篷”,或者您喜欢的任何其他配置,看起来很酷。

Over the last couple of weeks, though, I’ve taken a bigger interest in back-end development (motivated in part by a turbulent relationship between myself and CSS). I’d read about how it is possible to install Ubuntu Linux on a Chromebook (if I understand correctly, ChromeOS itself is basically built upon an underlying Linux kernel). I might yet do this, but it appears to be a slightly involved process that requires switching to developer mode, and wipes the local storage and disables all the nice security features ChromeOS is known for. I decided to look for an alternative.

但是,在过去的几周中,我对后端开发产生了更大的兴趣(部分原因是我和CSS之间的动荡关系)。 我已经读过有关如何在Chromebook上安装Ubuntu Linux的信息(如果我理解正确,ChromeOS本身基本上是基于底层Linux内核构建的)。 我可能还没有这样做,但是这似乎是一个稍微复杂的过程,需要切换到开发人员模式,并且擦除本地存储并禁用ChromeOS众所周知的所有出色的安全功能。 我决定寻找替代方案。

And I found one that works remarkably well. You see, Google have recently brought Android apps to some Chromebook models — and a few design/UX issues aside, anything that runs on your Android phone should run smoothly on ChromeOS. One such app I’ve installed is Termux — a Linux emulator for Android, no rooting required. I’ve been playing around with it the last few days, and suffice to say, I’m very impressed. Fredrik Fornwall has done an incredible job.

我发现一个效果很好。 您会发现,Google最近将Android应用程序带入了某些Chromebook机型-除了一些设计/ UX问题之外,您Android手机上运行的所有内容都应在ChromeOS上顺利运行。 我已经安装了一个这样的应用程序,即Termux-一款适用于Android的Linux模拟器,无需生根。 最近几天我一直在玩它,可以说,我印象深刻。 弗雷德里克·福恩沃尔(Fredrik Fornwall )做得非常出色。

I got started with a pair of articles written by Aurélien Giraud — and bam! Before I’d finished my morning coffee, I had a Node.js server and NeDB database up and running locally on my Chromebook — no scary developer mode necessary! If you have an Android device, I’d totally recommend bookmarking Aurélien’s tutorial and trying it out. You’ll have a Node.js server running on your phone in minutes.

我从AurélienGiraud撰写的两篇文章开始-ba! 早上喝完咖啡之前,我已经在Chromebook上建立了Node.js服务器和NeDB数据库并在本地运行-无需使用可怕的开发人员模式! 如果您使用的是Android设备,则完全建议您将Aurélien的教程添加为书签并进行尝试。 您将在几分钟内在电话上运行一个Node.js服务器。

Now I’m getting on just fine with Node, but I’m also interested in trying out a few other server-side languages —to see what the options are before narrowing down and picking one to focus on. One language I’ve been reading about is Go, introduced by Google back in 2009. It’s been doing alright lately and is growing in popularity — in fact, it has been named 2016’s Programming Language of the Year.

现在,我对Node的了解还不错,但是我也想尝试其他几种服务器端语言-在缩小范围并选择一个重点之前,先了解一下这些选项。 我一直在阅读的一种语言是Go ,它于2009年由Google引入。它最近运行得很好,并且越来越流行-实际上,它已被评为2016年度编程语言

Go is similar in some respects to languages like C and C++, and its design was indeed influenced by them. However, a primary motivation for creating Go in the first place was a dislike of the complexity of these long-established languages. As a result, Go is intentionally a much simpler language to use.

Go在某些方面类似于C和C ++等语言,并且其设计确实受到了它们的影响。 但是,首先创建Go的主要动机是不喜欢这些历史悠久的语言的复杂性。 结果,Go故意成为一种更简单的语言。

简单多少? (How much simpler?)

For instance, there is no ‘while’ loop in Go. No, when it comes to loops, you’ve got one choice and one choice only: the ‘for’ loop.

例如,Go中没有“ while”循环。 不,当涉及到循环时,您只有一种选择,只有一种选择:“ for”循环。

//basically a 'while' loop:
for i < 1000 {
  //something
  i++
  }

Type inference is optional. You can declare and initialise a variable the long way, or take a shortcut and assign type implicitly.

类型推断是可选的。 您可以长期声明和初始化变量,也可以采用快捷方式并隐式分配类型。

var x int = 2

//is the same as:

x := 2

‘If’ and ‘else’ statements are pretty straightforward:

“ if”和“ else”语句非常简单:

x := 5

if x > 10 {
  fmt.Println("Greater than 10")
} else {
  fmt.Println("Less than or equal to 10")
}

Go is also fast to compile and comes with all sorts of helpful packages available in the standard library, which is well-documented online. It’s been used in a number of projects, including some by household names such as Google, Dropbox, Soundcloud, Twitch and Uber.

Go还可以快速编译,并在标准库中提供了各种有用的软件包,该库在网上有充分的文档记录。 它已在许多项目中使用 ,包括一些家喻户晓的名称,例如Google,Dropbox,Soundcloud,Twitch和Uber。

I reasoned that if it’s good enough for them, it’s probably worth taking a look at. For anyone else taking their first steps into back-end development, I’ve put together a little tutorial, based upon my experiments with Go using Termux. If you have an Android device, or indeed a Chromebook with access to the Play Store, then get Termux installed and running, and we’re ready to go (EDIT: pun not actually intended).

我认为,如果对他们来说足够好,那就值得一看。 对于任何其他迈向后端开发的第一步的人,我根据我在Termux上使用Go进行的实验,整理了一些教程。 如果您拥有Android设备,或者实际上拥有可以访问Play商店的Chromebook,那么就可以安装并运行Termux,我们就可以开始使用了(编辑:pun实际上不是想要的)。

If you have a conventional Linux device, feel free to join in as well! The instructions for the server program itself should work just fine on any platform that supports Go.

如果您有传统的Linux设备,请随时加入! 服务器程序本身的指令在任何支持Go的平台应该可以正常工作

与Termux同行 (Get Go-ing With Termux)

Termux, like any other Android app, is very straightforward to download and install. Just search the Play Store, and hit INSTALL. Once it’s ready, open it up. You should have a nice blank command line interface looking back at you. I’d strongly recommend using a physical keyboard (either built-in, or micro-USB or Bluetooth connected), but if you don’t have one to hand, I’ve heard good things about another Android app called Hacker’s Keyboard.

与其他任何Android应用程序一样,Termux的下载和安装非常简单。 只需搜索Play商店,然后点击“安装”即可。 准备就绪后,将其打开。 您应该有一个不错的空白命令行界面,回头看看。 我强烈建议您使用物理键盘(内置的,微型USB或蓝牙连接的),但是如果您手边没有键盘,我听说过另一款名为Hacker's Keyboard的Android应用程序的好处。

As covered in Aurélien’s tutorial from last year, Termux comes with very little pre-installed. Run the following commands in the terminal:

正如去年Aurélien的教程中所述,Termux几乎没有预装。 在终端中运行以下命令:

$ apt update$ apt upgrade
$ apt install coreutils

Good. Everything’s up-to-date, and coreutils will help you navigate the file system a little easier. Let’s check where we are in the directory tree.

好。 一切都是最新的,coreutils将帮助您更轻松地浏览文件系统。 让我们检查一下目录树中的位置。

$ pwd

This should return a path name, showing where you currently are in the directory. If we’re not already there, let’s navigate to the ‘home’ folder, and see what’s inside:

这应该返回一个路径名,显示您当前在目录中的位置。 如果还不存在,请导航至“ home”文件夹,然后查看其中的内容:

$ cd $HOME && ls

Ok, let’s make a new directory for our Go tutorial, and navigate in there. Then, we can create a new file, called ‘server.go’.

好的,让我们为Go教程创建一个新目录,并在其中导航。 然后,我们可以创建一个名为“ server.go”的新文件。

$ mkdir go-tutorial && cd go-tutorial
$ touch server.go

If we type ‘ls’, we will see this one file in our directory. Now, let’s get ourselves a text editor. Aurélien’s tutorial introduces you to Vim, and if you’d prefer use that, then by all means do so. A slightly more ‘beginner-friendly’ editor, which I’ll be using here, is one called nano. Let’s install that, and open our server.go file:

如果键入“ ls”,我们将在目录中看到该文件。 现在,让我们为自己准备一个文本编辑器。 Aurélien的教程向您介绍了Vim,如果您愿意使用它,则一定要这样做。 我将在这里使用的“初学者友好”编辑器叫nano。 让我们安装它,然后打开我们的server.go文件:

$ apt install nano
$ nano server.go

Great! Now we can start typing as much code as we like. But before we do, let’s install the Go compiler, because we’ll kinda need this for our code to be of any use. Quit nano with Ctrl+X, and from the command line, type:

大! 现在,我们可以开始输入尽可能多的代码。 但是,在执行此操作之前,我们先安装Go编译器,因为对于我们的代码来说,我们将需要使用它。 使用Ctrl + X退出nano,然后在命令行中键入:

$ apt install golang

Now, let’s go back into nano, and start writing our server code!

现在,让我们回到nano,开始编写我们的服务器代码!

构建一个简单的Web服务器 (Building a Simple Web Server)

We’re going to write a simple program that launches a server, and serves a HTML page that lets the user enter a password to login and see a welcome message (or a “Sorry, try again”-type message if the password is wrong). In nano, begin with the following:

我们将编写一个简单的程序来启动服务器,并提供一个HTML页面,该页面允许用户输入密码登录并查看欢迎消息(如果密码错误,则显示“抱歉,请重试”类型的消息) )。 在nano中,从以下内容开始:

//Build a web server

package main

import (
  "fmt"
  "net/http"
  )

What we’ve done is create a package. Go programs always run in packages. It’s a way of storing and organizing code, and lets you call functions from other packages nice and easily. In fact, that’s the next thing we’ve written. We’ve told Go to import the ‘fmt’ package, and the ‘http’ package from the ‘net’ directory within the standard library. This gives us access to functions that lets us play around with ‘formatted I/O’, and HTTP requests and responses.

我们要做的是创建一个包。 Go程序始终在程序包中运行。 这是一种存储和组织代码的方式,使您可以轻松便捷地从其他包中调用函数。 实际上,这是我们接下来要写的东西。 我们已经告诉Go从标准库的“ net”目录中导入“ fmt”包和“ http”包。 这使我们能够访问使我们能够处理“格式化的I / O”以及HTTP请求和响应的功能。

Now, let’s get this thing online. A few lines down, let’s write the following code:

现在,让我们将此东西在线。 往后几行,让我们编写以下代码:

func main() {
  http.ListenAndServe(":8080",nil)
  fmt.Println("Server is listening at port 8080")
  }

Like C, C++, Java etc., Go programs enter with a ‘main()’ function. We’ve told the server to listen out for requests at port 8080 (although feel free to choose a different number), and to print out a message letting us know that’s what it’s doing.

像C,C ++,Java等一样,Go程序使用“ main()”函数输入。 我们已经告诉服务器在8080端口监听请求(尽管可以选择其他数字),并打印一条消息,让我们知道它正在做什么。

That’ll do for now! Let’s save the file (Ctrl+O), exit (Ctrl+X) and run our program. At the command line, type:

现在就做! 让我们保存文件(Ctrl + O),退出(Ctrl + X)并运行我们的程序。 在命令行中,键入:

go run server.go

This will ask the Go compiler to both compile and run the program. After a short pause, the program should run. You’ll hopefully see the following output:

这将要求Go编译器编译并运行该程序。 短暂的暂停后,程序应运行。 希望您会看到以下输出:

Server is listening at port 8080

Brilliant! Your server is listening for requests at port 8080. Unfortunately, it has no idea what to do with any requests it receives, because we haven’t told it how to respond. That’s the next step. Interrupt the server program with Ctrl+C, and reopen server.go in nano.

辉煌! 您的服务器正在侦听端口8080上的请求。不幸的是,它不知道如何处理收到的任何请求,因为我们还没有告诉它如何响应。 那是下一步。 使用Ctrl + C中断服务器程序,然后在nano中重新打开server.go。

发送回应 (Sending a Response)

We need the server to ‘handle’ requests, and write back appropriate responses. Thankfully, the ‘http’ package we imported makes this easy to do.

我们需要服务器来“处理”请求,并写回适当的响应。 值得庆幸的是,我们导入的“ http”包使此操作变得容易。

For the sake of readability, let’s insert the following code between the import() statement and the main() function. We could just carry on below the main() function, however, and all would be fine. Do it your way!

为了便于阅读,让我们在import()语句和main()函数之间插入以下代码。 我们可以只在main()函数下面进行操作,一切都很好。 用你的方式做!

Anyway, let’s write a handler function.

无论如何,让我们编写一个处理程序函数。

func handler (write http.ResponseWriter, req *http.Request) {
  fmt.Fprint(write, "<h1>Hello!</h1>")
  }

This is a function that takes two arguments, write and req. These are assigned types ResponseWriter and *Request, which are defined in the ‘http’ package. We then ask the server to write some HTML in response.

这个函数需要两个参数, writereq 。 这些被分配了类型ResponseWriter* Request ,它们在“ http”包中定义。 然后,我们要求服务器编写一些HTML作为响应。

In order to use this function, we need to call it within the main() function. Add the code in bold font below:

为了使用此函数,我们需要在main()函数中调用它。 在下面添加粗体代码:

func main() {
  http.ListenAndServe(":8080",nil)
  fmt.Println("Server is listening at port 8080")
  http.HandleFunc("/", handler)
  }

The line we’ve added calls HandleFunc() from the ‘http’ package. This takes two arguments. The first is a string, and the second refers to the handler() function we wrote just a moment ago. We’re asking the server to handle all requests to the web root “/” with the handler() function.

我们添加的行从“ http”包中调用HandleFunc()。 这需要两个参数。 第一个是字符串,第二个是我们刚才编写的handler()函数。 我们要求服务器使用handler()函数处理对Web根目录“ /”的所有请求。

Save and close server.go, then from the console, run the server again.

保存并关闭server.go,然后从控制台再次运行服务器。

go run server.go

Again, we should see the output message, letting us know the server is listening out for requests. Well, why don’t we send it a request? Just open up your web browser and visit http://localhost:8080/.

同样,我们应该看到输出消息,让我们知道服务器正在侦听请求。 好吧,为什么我们不发送请求呢? 只需打开您的Web浏览器并访问http:// localhost:8080 /即可

Chromebooks tend to be pretty opinionated about which browser you should use, but I found Chrome to be somewhat uncooperative when it came to connecting to any localhost ports. Installing the Mozilla Firefox for Android app from the Play Store resolved this.

Chromebook对于应该使用哪种浏览器往往持谨慎态度,但是我发现Chrome在连接到任何本地主机端口时有些不合作。 通过从Play商店安装Mozilla Firefox for Android应用程序解决了此问题。

Alternatively, if you’d like to stay entirely within Termux (and why not?), then check out Lynx. It’s a text-based browser which has been around since 1992. There’s no images, no CSS, and certainly no JavaScript. For the purposes of this tutorial though, it does the job nicely. Install and run with:

另外,如果您想完全呆在Termux(为什么不呢?)中,请查看Lynx。 这是一个基于文本的浏览器,自1992年以来一直存在。没有图像,没有CSS,当然也没有JavaScript。 不过,出于本教程的目的,它可以很好地完成工作。 安装并运行:

$ apt install lynx
$ lynx localhost:8080

If all is well, you should be greeted in your browser of choice with a heading saying “Hello!” If not, head back into nano and review server.go. Errors I made the first time round included using curly braces {} instead of brackets for the import() statement. There were also a couple of stray commas masquerading as dots (maybe I should use Ctrl+Alt+’+’ to increase the font size in Termux).

如果一切顺利,您应该在所选的浏览器中看到一个标题为“ Hello!”的字样。 如果没有,请回到nano并查看server.go。 我第一次出现的错误包括使用花括号{}代替了import()语句的括号。 还有一些伪装成点的流浪逗号(也许我应该使用Ctrl + Alt +'+'来增加Termux中的字体大小)。

世界上最独家的网站 (The World’s Most Exclusive Website)

Our server now responds to HTTP requests with a nice short line of HTML. Not exactly the next Facebook, but one step closer than we were before. Let’s make it a bit more interesting.

现在,我们的服务器使用很短HTML响应HTTP请求。 不完全是下一个Facebook,而是比以前更近了一步。 让我们使其更加有趣。

To recap: we’re going to make a page that asks the user for a password. If the password is wrong, the user gets a warning message telling them so. If it is correct, then the user receives a great big message saying “Welcome!” As it’s your own server on your own machine, and only you will know the password, it’s going to be a very exclusive website.

回顾一下:我们将创建一个页面,要求用户输入密码。 如果密码错误,则用户会收到一条警告消息,告诉他们。 如果正确,则用户会收到一条很大的大消息,说“欢迎光临!” 由于它是您自己计算机上的服务器,并且只有您自己知道密码,因此它将是一个非常专有的网站。

First off, let’s make the HTML response a bit more interesting. Go back to the handler() function we wrote before. Paste in all of the code in bold in place of what’s already there (it’s all one line). Careful with the quote marks! I’ve started and ended the string with double-quotes, and used single-quotes within the HTML section. Make sure you’re consistent.

首先,让我们使HTML响应更加有趣。 回到我们之前编写的handler()函数。 以粗体粘贴所有代码,以代替已存在的内容(全部为一行)。 小心引号! 我在字符串的开头和结尾都使用了双引号,并在HTML部分中使用了单引号。 确保您保持一致。

func handler (write http.ResponseWriter, req *http.Request) {
  fmt.Fprint(write, "<h1>Login</h1><form action='/log-in/' method='POST'> Password:<br> <input type='password' name='pass'><br> <input type='submit' value='Go!'></form>")
  }

When we run the server, the HTML should render the following page:

当我们运行服务器时,HTML应该呈现以下页面:

Now, I’m aware that I’m assuming a little familiarity with HTML here. Briefly, what we have is a header and a form. The form’s ‘action’ attribute is called ‘/log-in/’ and its method is set to POST. There are two input fields: one for password entry, and another to submit the form. The password field is named “pass”. We’ll need to refer to these names later on.

现在,我知道我在这里假设对HTML有点熟悉。 简而言之,我们拥有的是标题和表格。 表单的“操作”属性称为“ / login /”,其方法设置为POST。 有两个输入字段:一个用于输入密码,另一个用于提交表单。 密码字段被命名为“ pass”。 稍后我们将需要引用这些名称。

So what happens if we enter a password and submit it? Well, we’re making another HTTP request (“/log-in/”) to the server, so we need to write another function that handles this request. Back to Termux, and open up server.go in your text editor of choice.

那么,如果我们输入密码并提交,会发生什么? 好吧,我们正在向服务器发出另一个HTTP请求(“ / login /”),因此我们需要编写另一个函数来处理该请求。 返回Termux,然后在您选择的文本编辑器中打开server.go。

We’re going to make another function (personally, I’d write it between handler() and main(), but do whatever suits you). This is another function to handle HTTP requests — this time, to “/log-in/” requests, which are made whenever the user submits the form we made earlier.

我们将创建另一个函数(个人而言,我会在handler()和main()之间编写它,但会做一些适合您的事情)。 这是另一个处理HTTP请求的功能-这次,是对“ / login /”请求的处理,每当用户提交我们之前提交的表单时,都会发出该请求。

func loginHandler (write http.ResponseWriter, req *http.Request){
   password := req.FormValue("pass")
      if password == "let-me-in" { 
        fmt.Fprint(write, "<h1>Welcome!</h1>")
      } else {
        fmt.Fprint(write, "<h3>Wrong password! Try again.</h3>")
        }
   }

As before, this function has two arguments, write and req, which are assigned the same types as defined in the ‘http’ package.

和以前一样,此函数有两个参数writereq ,它们被赋予与“ http”包中定义的相同的类型。

We then create a variable called password, which we set equal to the ‘value’ of the request form’s input field called “pass”. Notice the implicit type assignment with the use of “:=”? We can do this because the password field’s value will always be sent as a string.

然后,我们创建一个名为password的变量,将其设置为等于请求表单输入字段“ pass”的“值”。 注意使用“:=”的隐式类型分配吗? 我们这样做是因为password字段的值将始终作为字符串发送。

Next up is an ‘if’ statement, using the “==” comparison operator to check if password is identical to the string “let-me-in”. This is of course, how we’re defining the correct password. You can change this string to whatever you like.

接下来是一个“ if”语句,使用“ ==”比较运算符检查密码是否与字符串“ let-me-in”相同。 当然,这就是我们定义正确密码的方式。 您可以将此字符串更改为任意字符串。

If the strings are identical, you’re in! For now, we’re printing out a boring “welcome” message. We’ll change that in a minute.

如果字符串相同的,你在! 目前,我们正在打印无聊的“欢迎”消息。 我们将在一分钟内更改它。

Else, if the strings are not identical, we’re printing out a “try again” message. Again, we could do with making that a little more interesting. For a start, it’d be useful if the password form was still available to the user. Add in the following code in bold. All it is, is the same password form HTML from before.

否则,如果字符串相同,我们将打印出“重试”消息。 同样,我们可以做些有趣的事情。 首先,如果用户仍然可以使用密码表单,那将很有用。 以粗体添加以下代码。 就是这样,就是以前HTML密码表单。

func loginHandler (write http.ResponseWriter, req *http.Request){
  password := req.FormValue("pass")
  if password == "let-me-in" {
    fmt.Fprint(write, "<h1>Welcome!</h1>")
    } else {
      fmt.Fprint(write, "<h1>Login</h1><form action='/log-in/' method='POST'> Password:<br> <input type='password' name='pass'><br> <input type='submit' value='Go!'></form>;<h3 style='color: white; background-color: red'>Wrong password! Try again.</h3>")
      }
    }

I’ve also added some simple styling to the “try again” message. Totally optional, but why not? Let’s do the same for the “welcome” message:

我还在“重试”消息中添加了一些简单的样式。 完全可选,但是为什么不呢? 让我们对“欢迎”消息做同样的事情:

func loginHandler (write http.ResponseWriter, req *http.Request){
  password := req.FormValue("pass")
  if password == "let-me-in" {
    fmt.Fprint(write, "<h1 style='color: white; background-color: navy; font-size: 72px'>Welcome!</h1>")
  } else {
    fmt.Fprint(write, "<h1>Login</h1><form action='/log-in/' method='POST'> Password:<br> <input type='password' name='pass'><br> <input type='submit' value='Go!'></form><h3 style='color: white; background-color: red'>Wrong password! Try again.</h3>")
    }
  }

Almost there! We’ve written out our loginHandler() function, but there’s no reference to it in our main() function. Add the following bold line of code:

差不多了! 我们已经写出了loginHandler()函数,但是在main()函数中没有引用它。 添加以下粗体代码行:

func main() {
  http.ListenAndServe(":8080",nil)
  fmt.Println("Server is listening at port 8080")
  http.HandleFunc("/", handler)
  http.HandleFunc("/log-in/", loginHandler)
  }

There! We’ve now told the server that if it receives a “/log-in/” request (which it will whenever the user clicks the submit button), use the loginHandler() function to make a response. We’re done! The whole code in server.go should look something like that below:

那里! 现在,我们告诉服务器,如果它接收到“ / loginHandler() /”请求(每当用户单击“提交”按钮时都会请求),请使用loginHandler()函数进行响应。 大功告成! server.go中的整个代码应如下所示:

//Build a web server
package main
import (
  "fmt"
  "net/http"
  )
  
func handler (write http.ResponseWriter, req *http.Request)
  fmt.Fprint(write, "&lt;h1>Login</h1><form action='/log-in/' method='POST'> Password:<br> <input type='password' name='pass'><br> <input type='submit' value='Go!'></form>")
  }

func loginHandler (write http.ResponseWriter, req *http.Request){
  password := req.FormValue("pass")
  if password == "let-me-in" {
    fmt.Fprint(write, "<h1 style='color: white;
    background-color: navy; font-size: 72px'>Welcome!</h1>")
    } else {
      fmt.Fprint(write, "<h1>Login</h1><form action='/log-in/' method='POST'> Password:<br> <input type='password' name='pass'><br> <input type='submit' value='Go!'></form><h3 style='color: white; background-color: red'>Wrong password! Try again.</h3>"
      )
      }
    }

func main() {
  http.ListenAndServe(":8080",nil)
  fmt.Println("Server is listening at port 8080")
  http.HandleFunc("/", handler)
  http.HandleFunc("/log-in/", loginHandler)
  }

Save and exit nano, and from the command line, let’s ask the Go compiler to build our server. This command compiles the program once, and lets us run it whenever we like thereafter.

保存并退出nano,然后从命令行要求Go编译器构建服务器。 该命令只编译一次程序,然后让我们在以后需要的时候运行它。

go build server.go

Give it a moment or two to compile, then enter the following command:

给它一两分钟的时间进行编译,然后输入以下命令:

./server

You should get the usual “listening” message. Now, if you go to the browser and access http://localhost:8080 (or whichever port number you went with), you’ll be asked to enter the password. If we enter it incorrectly, we get the following:

您应该会收到通常的“监听”消息。 现在,如果您转到浏览器并访问http:// localhost:8080 (或使用的任何端口号),系统将要求您输入密码。 如果输入错误,则会得到以下信息:

Whereas, if we enter the correct password:

而如果我们输入正确的密码:

结束语 (Concluding Remarks)

If you’ve read this far, I hope you’ve enjoyed the tutorial and found it helpful. I’ve pitched it at readers in a similar position as myself — kinda new to the whole web development thing and interested to learn more about how it works on the server-side, behind-the-scenes.

如果您已经阅读了本文,希望您喜欢本教程并发现它对您有所帮助。 我已经将它介绍给与我本人相似的读者,这对整个Web开发来说是新事物,并且有兴趣了解更多有关它在服务器端,幕后工作方式的信息。

Of course, the simple login page we made here still has a long way to go before it’s anything to write home about. You wouldn’t really write the HTML into the handler functions as we did here (Go’s html package has some nice templating options that I’m going to look into), nor would you define the correct password in an ‘if’ statement. It’d be much better to have a database of passwords (and usernames), which you’d query each time the server received a log-in request.

当然,我们在此处创建的简单登录页面还有很长的路要走,才可以写成一本书。 您不会像在这里那样真正地将HTML写入处理程序函数中(Go的html包中有一些我要研究的漂亮的模板选项),也不会在'if'语句中定义正确的密码。 拥有一个密码(和用户名)数据库会更好,每次服务器收到登录请求时都要查询该数据库。

To that end, Termux does offer a SQLite package, as well as various database packages available in Node.js. A cool extension to this tutorial would be to create a database of usernames and their passwords, and allow new users to be added. You’d begin by adding another input field, and altering the loginHandler() function.

为此,Termux确实提供了SQLite包以及Node.js中可用的各种数据库包。 本教程的一个不错的扩展是创建用户名及其密码的数据库,并允许添加新用户。 首先,添加另一个输入字段,然后更改loginHandler()函数。

I’ve already expressed my opinion of Termux — it’s remarkable, and I look forward to it only getting better as more packages become available. As well as Go and Node.js, I’ve successfully written and compiled/run simple programs in C, C++, CoffeeScript, PHP and Python 3.6, and there’s still other languages I haven’t yet looked at (anyone into Erlang/Lua/PicoLisp?)

我已经表达了对Termux的看法-这是很了不起的,我期待它随着越来越多的可用软件包而变得更好。 除了Go和Node.js,我还成功地编写和编译/运行了C,C ++,CoffeeScript,PHP和Python 3.6的简单程序,还有其他我还没有看过的语言(任何人都可以进入Erlang / Lua / PicoLisp?)

As for Go, my first encounter has been a positive one. I like its focus on simplicity, and I like the syntax, and the documentation is at a level that is accessible, yet pushes me to develop my understanding. For what a relative beginner’s opinion is worth on the matter, it feels like a cross between C++ and Python. To some extent, that’s probably exactly what it’s meant to be!

至于围棋,我的第一次相遇是积极的。 我喜欢它对简单性的关注,喜欢语法,并且文档处于可以访问的水平,但仍促使我加深理解。 对于这个问题,相对初学者而言,这是值得的,感觉就像C ++和Python之间的交叉。 在某种程度上,这可能正是它的含义!

翻译自: https://www.freecodecamp.org/news/how-i-built-a-web-server-using-go-and-on-chromeos-3b83e4c2da5f/

chromeos

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值