jonathan-fei.pro


  • Home

  • Tags

  • Categories

  • Archive

网络基础-HTTP

Posted on 2018-01-02 | In 网络基础

最近Rails项目部署的过程中遇到网络端口的问题及用到了http网络协议的知识,于是决定对这块知识进行回顾和重新梳理,这里推荐韩立刚老师的《计算机网络原理》一书,讲的很明白。以下为这次学习到的主要内容:

  • HTTP( Hyper Text Transfer Protocol)
  • WWW( World Wide Web),互联网上的网站共同组成万维网。

  • URL( Uniform Resource Locator),统一资源定位符,网站的网址。URL一般由四个部分组成:<协议>://<主机>:</端口>/<路径>,例如http://106.14.190.181:80/wx

一、HTTP协议版本:

1- HTTP1.0规定浏览器与服务器只保持短暂的连接,浏览器的每次请求都需要与服务器建立一个TCP连接,服务器完成请求处理后立即断开TCP连接,既不跟踪每个客户也不记录过去的请求。

2- HTTP1.1支持持续连接,即服务器在发送响应后,仍然在一段时间内保持这条TCP连接,使得同一个浏览器和该服务器可以继续在这条连接上传送后续的HTTP请求报文和响应报文。HTTP1.1的持续连接有两种工作方式,即非流水线方式和流水线方式。非流水线方式(理解为迅雷一次只能下载一个文件)的特点是客户在收到前一个响应后才能发送写一个请求。因此,在TCP连接建立后,客户每访问一次对象都要用去一个往返时间RTT,这种方式浪费服务器资源。流水线的特点(理解为迅雷一次可以下载多个文件)是客户在收到HTTP响应报文之前就能够发送新的请求报文。于是一个接一个的请求报文到达服务器后,服务器就可连续发回响应报文,这种方式使TCP连接中的空闲时间减少,提高了文档的下载效率。

3- HTTP请求报文与响应报文
(1) 请求报文:从客户端向服务器发送请求报文
请求报文由三个部分组成:分别是请求行,首部行,实体主体。请求报文的第一行“请求行”只有三个内容,即方法、请求资源的URL,以及HTTP的版本。方法就是对对象的操作,HTTP1.1协议中定义了八中方法,来表明对Request-URL指定资源的不同操作方式:GET、POST、PUT、DELETE、HEAD、TRACE、CONNECT、OPPIONS
(2)响应报文:从服务器到达客户端的应答

二、Cookie

HTTP是一种无状态的协议,当你注册登录一个网站后,当下次再打开这个网站后,需要再次输入账号与密码进行身份验证,服务器仅从网络连接上无从知道你的曾经登录的身份。如果希望服务器读取你的曾经登录的身份,那就需要在用户输入账号和密码后,服务器在用户的计算机存放一个通行证,来记录用户的身份和状态。以后再访问,网站(服务器)就会先读取客户端的通行证。服务器存放在客户端(浏览器)的通行证通常被称为cookie。

cookie实际上是一小段的文本信息(说明可以进行拷贝,也就是在其他浏览器导入cookie之后不用输入账号和密码就可以登录了)。客户端请求服务器,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie,客户端把浏览器会把cookie保存起来。当浏览器再请求该网站时,浏览器吧请求的网址连同该Cookie一同提交给服务器。服务器检查该Cookie,以此来辨认用户身份和状态。服务器还可以根据需要修改cookie的内容。

三、通过代理服务器访问网站

代理服务器英文全称为Proxy Server,其功能就是代理网络用户去取得网络信息。我们可以配置计算机通过Web代理服务器访问Web站点,而不直接访问网站。

使用代理服务器的场景:
(1)使用代理服务器,绕过防火墙封锁。
国内不允许网民访问国外的非法网站,在我国的防火墙上设置了拦截到这些网站的流量。但是国外有很多的web代理服务器,国内用户可以设置浏览器使用国外的代理商服务器,然后访问非法网站,就能成功。现在有很多“翻墙”软件,其实质就是使用国外代理服务器绕过国内封锁,故称为“翻墙”。
(2)提高访问速度
通常代理服务器可以缓存用户访问过的内容,当其他用户再访问相同的URL时,由代理服务器直接从缓存中找到要访问的信息,传给用户,已提高访问速度。例如,在企业内网部署一个Web代理服务器,能节省上网带宽。
(3)隐藏真实IP
上网者也可以通过这种方法隐藏自己的IP。有些网站的论坛会记录发帖人的IP地址。如果你不打算让论坛记录你真是的IP地址,就可以使用代理服务器访问该网站,发帖,这样只会记录下代理的地址,从而隐藏自己的IP地址。

国内外有很多免费的代理服务器,例如西刺免费代理。上面可以看到免费的代理服务器,在浏览器中设置使用这些代理服务器访问Internet。

注册与登录

Posted on 2017-12-21 | In Ruby

rails 中的gem devise提供了注册与登录的功能,用起来比较方便。但是为了自身编程能力,决定学习如何自写出注册与登录功能。

注册功能

用户注册即创建一个用户,这时会用到我们所熟知的CRUD。理解起来很容易,但是做起来并没有那么简单。

首先需要生成user的model,并对其字段进行约束,通常情况下,会是name与email,例如name与email都不为空、长度、格式,为邮箱加索引等,把这些设置好之后,需要设置路由,控制器,还有视图。

Model

约束字段。例如name与email的长度、格式、不为空,密码长度等,且为邮箱加索引。

routes.rb

设置注册路由,一般会是get '/signup', to: 'users#new' post '/signup', to: 'users#create'

Views

设置注册表单。其中会用到form_for或者 simple_form_for

Controllers

编写users#new与 users#create

验证用户

验证用户会用密码,因为我们会为user增加一个字段名称password_digest,在user的model中,添加has_secure_password这个方法(因为has_secure_password这个方法调用唯一要求就是对应的model中有password_digest 字段),它有三个作用: (1) 在数据库层中的password_digest中存储安全的密码哈希值(2)获得一对虚拟属性,password password_confirmation,而且创建对象时会执行存在性验证和匹配验证(3)获得authenticate方法,如果密码正确,返回用户对象,如果密码错误,返回false。 要想生成不可逆的密码哈希值,我们需要用到gem 'bcrypt',它的作用就是生成哈希密码值。这样即使‘脱库’,用户的真实密码也不会丢失。

部分gem总结

Posted on 2017-09-07 | In Ruby

1.gem ‘devise’ ———————————— 登录系统

安装须知: 依次执行bundle install rails g devise:install rails g devise user rake db:migrate,最后重新rails s。

2.gem ‘bootstrap-sass’ ———————————— 前端开发套件

安装须知:
(1) 依次执行bundle install mv app/assets/stylesheets/application.css app/assets/stylesheets/application.scss;
(2)

app/assets/stylesheets/application.scss
1
2
3

+@import "bootstrap-sprockets";
+@import "bootstrap";

最后重新rails s

3.gem ‘simple_form’ ———————————— 简化表单

安装须知: 依次执行bundle install rails g simple_form:install --bootstrap,最后重新rails s

4.gem ‘font-awesome-rails’ ———————————— 图标套件

安装须知

(1)bundle install ,重新rails s
(2)

app/assets/stylesheets/application.scss
1
@import "font-awesome";

5.gem ‘better_errors’ ———————————— 更好的显示错误讯息

安装须知 bundle install 重启rails s

6.gem ‘annotate’ ———————————— 在主要用于model中显示栏位

安装须知 bundle install 重启rails s
执行annotate --exclude tests,fixtures,factories,serializers,
ps:每次新增栏位后,都要执行这个命令,才会在具体model里显示出所有建立的栏位提示。

7.gem ‘awesome_rails_console’ —————————- 让“金手指”变好看的套件

安装须知 bundle install 重启rails s

8.gem ‘carrier_wave’ gem ‘mini_magick’ ———————————— 用于上传图片(可能还有其他的功能)

安装须知 依次执行:bundle install rails g uploader image 重启rails s

两种方法实现收藏或者点赞功能

Posted on 2017-09-07 | In Ruby

收藏功能与点赞功能的实作十分类似,本文以购物车教程实作收藏功能为例。

方法一:

step1

一个用户可以收藏多个商品,一个商品可以被收藏很多次,因此这是多对多的关系。因此需要新增一个model,来当做product与suer的桥梁。$ rails g model collect user_id:integer product_id:integer,然后执行 rake db:migrate,然后为collect、user与product这三个model加上关联。

app/models/collect.rb
1
2
3
4
5
6
7
8
9

+ belongs_to :user
+ belongs_to :product
```

``` ruby app/models/product.rb

+ has_many :collects
+ has_many :collected_users, through: :collects, source: :user
app/models/user.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

+ has_many :collects
+ has_many :collected_products, through: :collects, source: :product

#加上是否收藏商品的判定
+ def is_collect_of?(product)
+ collected_products.include?(product)
+ end
```

#### step2
首先修改路由信息:
``` ruby config/routes.rb

+ resources :product do
+ member do
+ post :collect
+ post :uncollect
+ end
+ end

在controller里加上对应的method,

app/controllers/product_controllers.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14

+ def collect
+ @product = Product.find(params[:id])
+ current_user.collected_products << @product
+ flash[:notice] = "成功收藏商品"
+ redirect_to :back
+ end

+ def uncollect
+ @product = Product.find(params[:id])
+ currrent_user.collected_products.delete(@product)
+ flash[:warning] = "您已取消收藏该商品"
+ redirect_to :back
+ end

step3

在views中的相应位置加入收藏的显示

app/views/products/show.html.erb
1
2
3
4
5
6

+ <% if current_user && current_user.is_collect_of?(@product) %>
+ <%= link_to(“取消收藏”, uncollect_product_path(@product), :method => :post, class: "btn btn-danger btn-lg" )%>
+ <% else %>
+ <%= link_to("收藏“, collect_product_path(@product), :method => :post, class: "btn btn-danger btn-lg" )%>
+ <% end %>

方法二

step1

同样,终端执行 rails g model colloect, 编辑 db/migrate/XXXXXXXX_create_collects.rb

db/migrate/XXXXXXXX_create_collects.rb
1
2
3
4
5
6
7
8
9
  class CreateCollects < ActiveRecord::Migration[5.0]
def change
create_table :collects do |t|
+ t.integer :user_id, :index => true
+ t.integer :product_id, :index => true
t.timestamps
end
end
end

之后执行 rake db:migrate

编辑app/models/collect.rb,加上关联

app/models/collect.rb
1
2
+ belongs_to :user
+ belongs_to :product

编辑 app/models/product.rb,加上关联

app/models/product.rb
1
2
3
4
5
6
7
8
9
10
11
12
  + has_many :collects, :dependent => :destroy
+ had_many :collected_users, through: :collects, source: :user

+ def find_collect(user)
+ self.collects.where( :user_id => user.id).first
+ end
```

编辑 `app/model/user.rb`,加上关联
``` ruby app/models/user.rb
+ has_many :collects, :dependent => :destroy
+ has_many :collected_products, through: :collects, source: :product

step2

编辑路由信息

config/routes.rb
1
2
3
4
5
6
+ resource :products do
+ member do
+ post :collect
+ post :uncollect
+ end
+ end

在controller中添加:

app/controllers/product_controller.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
+ def collect
+ @product = Product.find(params[:id])
+ unless @product.find_collect(cuurent_user)
+ Collect.create( :user => current_user, :product => @product)
+ flash[:notice] = "您已成功收藏该商品"
+ end
+ redirect_to :back
+ end

+ def uncollect
+ @product = Product.find(params[:id])
+ collect = @product.find_collect(current_user)
+ collect.destroy
+ flash[:warning] = "您已取消收藏该商品"
+ redirect_to :back
+ end

Step3

最后一歩,就是要在 app/views/products/show.html.erb中加上收藏的按钮

app/views/products/show.html.erb
1
2
3
4
5
6
7
8
9
……略
+ <% if current_user %>
+ <% if @product.find_collect(current_user)%>
+ <% =link_to("取消收藏", uncollect_product_path(@product), :method => :post, class: "btn btn-danger btn-lg")%>
+ <% else %>
+ <%= link_to("收藏", collect_product_path(@product), :method => :post, class: "btn btn-primary btn-lg")%>
+ <% end %>
+ <% end %>
……略

成果展示

利用ransack做搜索功能

Posted on 2017-09-07 | In Ruby

本篇教程基于自己的一个小项目,用户可以搜索网站上其他用户发表过的文章。

第一歩:

安装gem ransack

ransack会用数据库的LIKE语法来做搜寻,虽然比较方便,但它会依次检查资料是否符合,而不会使用数据库的索引。如果数据比较庞大的话,利用ransack将不会是一个好的选择。这时候我们就可以安装专门的全文搜索引擎,例如Elasticsearch

Gemfile
1
+  gem 'ransack'

$ bundle,重启 rails s

第二歩

controller与config的设定

1、设置路由

config/routes.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
  Rails.application.routes.draw do
devise_for :users
resources :posts do
+ collection do #我们会搜索出所有符合关键字的文章,结果为复数,因此用collection,而不是member
+ get :search
+ end
end
end
```

#### 2、设置controller
主要设置通过哪些关键词进行搜索。
```ruby app/controllers/posts_controller.rb

class PostsController < ApplicationController
before_action :validate_search_key, only: [:search]

def search
if @query_string.present?
@posts = search_params #搜索post的关键词
end
end

protected # 放在最后

def validate_search_key
# gsub 是Ruby中正则表达式的方法,它会切换所有匹配到的部分
@query_string = params[:q].gsub(/\\|\'|\/|\?/, "")if params[:q].present?
end

def search_params
Post.ransack({:title_or_content_cont => @query_string}).result(distinct: true)
#title与content是post的两个栏位,而我们的关键词出自这里
end
end

第三歩

views的设定

1、导航栏的显示

app/views/common/_navbar.html.erb
1
2
3
4
5
6
7
8
9
10
 <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
+ <ul class="nav navbar-nav">
+ <li>
+ <div class="form-group form-inline search-bar">
+ <%= render :partial => "posts/search_bar"%>
+ </div>
+ </li>
+ </ul>
…… 略
</div>

执行$ touch app/views/posts/_search_bar.html.erb,并编辑

app/views/posts/_search_bar.html.erb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
 <div class="row">
<div class="col-sm-9 col-lg-8 col-lg-offset-2">
<%= form_tag search_posts_path, :class => "posts-search-form", :method => :get do %>
<div class="input-group">
<input type="text" class="form-control search-bar-input" name="q" value="<%= params[:q] %>" placeholder="关键词">
<span class="input-group-btn">
<button type="submit" class="btn btn-default search-bar-submit">
<span class="glyphicon glyphicon-search"></span>
</button>
</span>
</div>
<% end %>
</div>
</div>

2.搜索反馈页面
新增 app/views/posts/search.html.erb

app/views/posts/search.html.erb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<div class="minHeight1000 bg-gray">
<div class="search-page w1200 pt30 bc">
<% if @posts.present? %>
<h5 class="collection search-count">已为您找到<%= @posts.count %>篇相关文章</h5>
<% else %>
<p class="tc mt100">未搜索到任何文章,要不换个关键词试试?</p>
<% end %>
</div>

<div class="container">
<% @posts.each do |post| %>

<div class="panel panel-default">
<div class="panel-body">
<%= post.title %>
<br/>
<br/>
<span id="psot-thumbsup-<%= post.id%>" class=" label label-success"><%= post.likes.count%>👍</span>
<div class="text-right">

<% if !current_user.is_collect_of?(post) %>
<%= link_to("收藏", collect_post_path(post), method: :post, class: "btn btn-sm") %>
<% else %>
<%= link_to("取消收藏", uncollect_post_path(post), method: :post, class: "btn btn-sm") %>
<% end %>
</div>
</div>

</div>

<% end %>
</div>
</div>

效果图

Hello World

Posted on 2017-09-06

Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.

Quick Start

Create a new post

1
$ hexo new "My New Post"

More info: Writing

Run server

1
$ hexo server

More info: Server

Generate static files

1
$ hexo generate

More info: Generating

Deploy to remote sites

1
$ hexo deploy

More info: Deployment

123
jonathan-fei

jonathan-fei

Stay hungry. Stay foolish.

26 posts
5 categories
46 tags
GitHub E-Mail Twitter Weibo
© 2018 jonathan-fei
Powered by Hexo
|
Theme — NexT.Pisces v5.1.3