node部署代理服务器全流程

启动node代理服务器:

  • 安装nvm: 如何安装nvm
  • 使用nvm安装node服务,要求版本14以上
  • 安装node中间件:npm install express http-proxy-middleware
  • node代码,所有访问localhost/api/?的请求都会被转发到https://final_host_site.com/?:
const express = require('express');
const { createProxyMiddleware } = require('http-proxy-middleware');

const app = express();

const targetUrl = 'https://final_host_site.com';

// 代理配置
const options = {
  target: targetUrl, // 目标主机
  changeOrigin: true, // 需要虚拟托管站点
  pathRewrite: {
    '^/api': '',
  },
  onProxyReq: (proxyReq, req, res) => {
    console.log(`[Proxy] ${req.method} ${req.path}`);
  },
};

// 使用中间件
app.use('/api', createProxyMiddleware(options));

// 监听端口
const PORT = 3000;
app.listen(PORT, () => {
  console.log(`Server is running on http://localhost:${PORT}`);
});

使用pm2命令管理程序,保证出问题时可以自动重启

npm install pm2 -g

pm2 start server.js --name myapp

pm2 startup

pm2 save

安装lnmp服务:

wget https://soft.lnmp.com/lnmp/lnmp2.0.tar.gz -O lnmp2.0.tar.gz && tar zxf lnmp2.0.tar.gz && cd lnmp2.0 && ./install.sh lnmp
配置nginx:
server
    {
        listen 80;
        #listen [::]:80;
        server_name www.myhost.com;
            location / {
                    proxy_pass http://localhost:3000;
            }

    }

server
    {
        listen 443 ssl http2;
        #listen [::]:443 ssl http2;
        server_name wishapi.vvip.tech ;

        ssl_certificate /usr/local/nginx/conf/ssl/www.myhost.com/fullchain.cer;
        ssl_certificate_key /usr/local/nginx/conf/ssl/www.myhost.com/www.myhost.com.key;
        ssl_session_timeout 5m;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
        ssl_prefer_server_ciphers on;
        ssl_ciphers "TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-128-GCM-SHA256:TLS13-AES-128-CCM-8-SHA256:TLS13-AES-128-CCM-SHA256:EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5";
        ssl_session_cache builtin:1000 shared:SSL:10m;
        # openssl dhparam -out /usr/local/nginx/conf/ssl/dhparam.pem 2048
        ssl_dhparam /usr/local/nginx/conf/ssl/dhparam.pem;
            location / {
                    proxy_pass http://localhost:3000;
            }
                access_log  /home/wwwlogs/www.myhost.com.logs;

    }

阿里云(国内)安装nvm

​nvm正常安装步骤:https://github.com/nvm-sh/nvm

wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash

直接使用nvm脚本安装的时候一直失败,应该是国内网络的问题,使用下面方案进行解决:

下载

cd /
wget https://github.com/nvm-sh/nvm/archive/refs/tags/v0.39.1.tar.gz
mkdir -p /.nvm
tar -zxvf v0.39.1.tar.gz -C /.nvm

配置

vim ~/.bashrc

复制

在文件末尾添加(注意修改nvm路径中的版本号)

export NVM_DIR="/.nvm/nvm-0.39.1"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"  # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"  # This loads nvm bash_completion

让配置文件生效

source ~/.bashrc

设置镜像

直接安装node和npm可能会安装失败,需要修改镜像

nvm node_mirror https://npm.taobao.org/mirrors/node/
nvm npm_mirror https://npm.taobao.org/mirrors/npm/

常见问题

  • 如果不是root用户,没有权限
sudo chmod 777 /.nvm

nvm基本使用

# 查看已安装的版本
nvm ls
# 安装指定版本的node
nvm install 16
# 切换node版本
nvm use 16

阿里云服务器安装图形界面gnome

  1. 购买阿里云服务器,推荐最低2G内存,推荐4G。 我这里使用的是2核2G突发实例,ubuntu20.04,一个月88元
  2. 通过管理终端连接Linux实例,详情请参见连接方式概述
  3. 执行以下命令,更新软件源。apt-get update
  4. 依次执行以下命令,安装GNOME桌面环境。apt-get install x-window-system-core apt-get install gnome-core
  5. 执行以下命令,启动图形化桌面。startx
  6. 关闭当前终端连接,通过ECS管理控制台的VNC连接实例,请参见通过密码认证登录Linux实例,确认图形化桌面环境安装成功。
  7. 如果使用vnc登录没有效果,执行init 5切换到图形界面

fastAdmin后台功能详解

FastAdmin是一款基于ThinkPHP5+Bootstrap的极速后台开发框架。优点见开发文档 介绍 – FastAdmin框架文档 – FastAdmin开发文档

在这里上传几张优秀的快速入门图:

 一张图解析FastAdmin中的表格列表的功能:(仅仅为了查找方便,如有侵权联系删除)

功能描述

请根据图片上的数字索引查看对应功能说明。

1.菜单名称和描述
默认生成的CRUD是没有菜单名称和描述显示的,如果需要显示则可以修改权限管理->菜单规则,给对应菜单的添加上备注信息后即可显示,支持HTML

2.TAB过滤选项卡
在一键生成CRUD时,如果表中存在status字段且为ENUM类型,则会生成相应的TAB过滤选项卡,如果需要生成其它字段的过滤选项卡则可以在使用php think crud时使用--headingfilterfield=你的字段名称来指定字段

3.通用搜索
通用搜索的的内容是根据bootstrap-table配置的字段columns决定的,渲染的内容及格式由FastAdmin自动进行渲染,如果需要禁用或删除某一选项,可以在JS中配置operate:false来删除通用搜索中的选项。例如通常情况下我们的在JS中进行字段的配置如下:

{field: 'createtime', title: __('Create Time')},

这里默认是启用的通用搜索,针对通用搜索,有以下几个常用的配置:

operate:'=' //用于查询时的操作符,默认为=,为false表示禁用此字段的通用搜索,支持!=、LIKE、NOT LIKE、>、<、>=<=、FIND_IN_SET、IN、NOT IN、BETWEEN、NOT BETWEEN、RANGE、NOT RANGE、NULL、NOT NULL、false
searchList: //用于渲染列表的数据,支持的格式有JSON Array、JSON Object、$.getJSON、Function
addclass: //用于给input或select添加额外的class属性
type: //用于定义input文本框的类型,默认为text
data: //用于给input或select添加额外的属性

常用配置示例如下:

//时间区间搜索
{field: 'createtime', title: __('Createtime'), operate: 'RANGE', addclass: 'datetimerange', formatter: Table.api.formatter.datetime},
//金额区间搜索
{field: 'money', title: __('Money'), operate: 'RANGE'},
//下拉列表搜索
{field: 'flag', title: __('Flag'), searchList: {"hot": __('Flag hot'), "index": __('Flag index'), "recommend": __('Flag recommend')}, operate: 'FIND_IN_SET', formatter: Table.api.formatter.label},
//动态下拉列表搜索
{field: 'type', title: __('Type'), searchList: $.getJSON("ajax/dynamicselect")},
//禁用通用搜索
{field: 'keywords', title: __('Keywords'), operate: false},

如果我们需要完全自定义我们的通用搜索栏,我们可以在配置bootstrap-table时定义searchFormTemplate选项来完全重写我们的通用搜索栏,具体请参考开发示例插件中的自定义搜索示例

4.工具栏按钮
FastAdmin在一键CRUD时会自动生成添加、编辑、删除、导入、更多按钮的HTML,这些按钮会根据用户所拥有的权限控制基是否显示或隐藏。我们可以在控制器对应的index.html视图文件中任意修改或删除对应的按钮。请特别注意这几个自动生成的按钮都通过基拥有的class属性来绑定相关的事件,例如添加按钮拥有btn-add这个class、框架所已经占用的class如下:

btn-add: 添加按钮使用
btn-edit: 编辑按钮使用
btn-del: 删除按钮使用
btn-import: 导入按钮使用
btn-more: 更多按钮使用
btn-multi: 指操作使用
btn-disabled: 添加此class后则只有在列表有选中数据时按钮才会变为可使用

如果我们想点击添加按钮后默认全屏,则可以给添加按钮加上data-area='["100%","100%"]'即可默认全屏
如果我们想自定义按钮并添加事件,我们需要在视图中添加相应的HTML代码,然后在对应的JS文件中添加按钮的执行事件,切记不可在视图中直接编写JS或jQuery代码来绑定事件

5.动态渲染统计信息
很多时候我们需要在页面额外显示服务端传回的动态数据,此时我们只需要在index.html视图中添加

<a href="javascript:;" class="btn btn-default" style="font-size:14px;color:dodgerblue;">
    <i class="fa fa-dollar"></i>
    <span class="extend">
        金额:<span id="money">0</span>
        单价:<span id="price">0</span>
    </span>
</a>

然后在控制器对应的JS中的index方法中添加以下的JS

//当表格数据加载完成时
table.on('load-success.bs.table', function (e, data) {
    //这里可以获取从服务端获取的JSON数据
    console.log(data);
    //这里我们手动设置底部的值
    $("#money").text(data.extend.money);
    $("#price").text(data.extend.price);
});

注意务必将这段代码添加在var table = $("#table");之后
其中data.extend.moneydata.extend.price就是我们在服务端动态返回的数据,如下

$result = array("total" => $total, "rows" => $list, "extend" => ['money' => 1024, 'price' => 888]);
return json($result);

通过以上配置即可动态显示服务端返回的额外数据

6.快速搜索
快速搜索在键入关键词时将实时从服务端搜索数据,如果你的数据表数据较大,建议关闭此功能,关闭的方法是使用search:false,其次快速搜索默认只会搜索主键id这个字段,如果你需要搜索其它字段,则需要在服务端你的控制器中定义$searchFields这个值,如下

protected $searchFields = 'id,name,title';

这样在快速搜索时将会搜索id,name,title这三个字段。
如果需要修改默认文本框的placeholder,可以在表格初始化前定义

$.fn.bootstrapTable.locales[Table.defaults.locale]['formatSearch'] = function(){return "自定义placeholder文本";};

7.浏览模式、显示隐藏列、导出、通用搜索
浏览模式可以切换卡片视图和表格视图两种模式,如果不需要此功能,可以设置showToggle: false
显示隐藏列可以快速切换字段列的显示和隐藏,如果不需要此功能,可以设置showColumns: false,如果想要表格中的字段列默认隐藏可以设置字段属性visible: false即可默认隐藏
导出按钮默认将导出整个表的所有行,如果需要仅导出当前分页的数据,需要设置exportDataType: 'basic',如果想导出选中的行,则可以设置为exportDataType: 'selected',如果不需要此功能,可以设置showExport: false
通用搜索指表格上方的搜索,通用搜索的表单默认是隐藏的,如果需要默认显示,需要设置searchFormVisible: true,如果不需要通用搜索功能,可以设置commonSearch: false。如果想要控制字段列不参考搜索则可以设置字段列属性为operate: false即可。

8.字段配置
默认字段的控制是根据控制器对应的JS来配置的,因此字段配置是通过JS,而在我们的视图index.html中是没有任何字段配置的,通常我们的配置如下:

columns: [
    [
        {checkbox: true},
        {field: 'id', title: __('Id')},
        {field: 'admin_id', title: __('Admin_id')},
        {field: 'category.name', title: __('分类名称'), formatter:Table.api.formatter.search},
        {field: 'category_id', title: __('Category_id'), visible: false},
        {field: 'flag', title: __('Flag'), searchList: {"hot": __('Flag hot'), "index": __('Flag index'), "recommend": __('Flag recommend')}, operate: 'FIND_IN_SET', formatter: Table.api.formatter.label},
        {field: 'genderdata', title: __('Genderdata'), searchList: {"male": __('Genderdata male'), "female": __('Genderdata female')}, formatter: Table.api.formatter.normal},
        {field: 'title', title: __('Title')},
        {field: 'image', title: __('Image'), formatter: Table.api.formatter.image},
        {field: 'images', title: __('Images'), formatter: Table.api.formatter.images},
        {field: 'createtime', title: __('Createtime'), operate: 'RANGE', addclass: 'datetimerange', formatter: Table.api.formatter.datetime},
        {field: 'updatetime', title: __('Updatetime'), operate: 'RANGE', addclass: 'datetimerange', formatter: Table.api.formatter.datetime, visible: false},
        {field: 'weigh', title: __('Weigh'), operate: false, visible: false},
        {field: 'switch', title: __('Switch'), searchList: {"1": __('Yes'), "0": __('No')}, formatter: Table.api.formatter.toggle},
        {field: 'status', title: __('Status'), searchList: {"normal": __('Normal'), "hidden": __('Hidden')}, formatter: Table.api.formatter.status},
    ]
]

字段配置的参数有

checkbox:true, //是否为首列复选框
field:'name' //字段名称,如果启用了关联查询这里可以使用别名,比如:category.name,请注意服务端返回的字段一一对应,如果使用了一个不存在的字段,将不会渲染任何数据
title:'名称' //字段标题,显示于头部的标题
operate:'=' //通用搜索的操作符,详见上方通用搜索介绍
visible:false //字段是否可见,为false时将默认不可见
formatter:Table.api.formatter.search //格式化显示的内容,FastAdmin内部定义了许多通用的格式化方法
events: //定义元素响应的事件
searchList: //定义通用搜索下拉列表的数据
addclass: //通用搜索文本框或下拉列表的额外class
type: //通用搜索文本框的类型
data: //通用搜索文本框或下拉列表的额外属性
buttons: //配置的按钮组

FastAdmin封装了许多常用的formatter方法,我们可以快速的调用即可。

> `Table.api.formatter.icon` 快速将字段渲染成一个按钮,仅支持Fontawesome按钮
> `Table.api.formatter.image` 快速将字段渲染成图片展示的形式
> `Table.api.formatter.images` 快速将字段渲染成多图片展示的形式,字段数据请以`,`进行分隔
> `Table.api.formatter.status` 快速将字段渲染成状态,默认`normal/hidden/deleted/locked`这四个状态
> `Table.api.formatter.url` 快速将字段渲染成URL框
> `Table.api.formatter.search` 快速将字段渲染成可搜索的链接,点击后将执行搜索
> `Table.api.formatter.addtabs` 快速将字段渲染成可添加到选项卡的链接,点击后将把链接添加到选项卡
> `Table.api.formatter.flag` 快速将字段渲染成标志,仅支持`index/hot/recommend/new`这四种标志
> `Table.api.formatter.label` 快速将字段渲染Label标签
> `Table.api.formatter.datetime` 快速时间戳数据渲染成日期时间数据
> `Table.api.formatter.operate` 操作栏固定按钮
> `Table.api.formatter.buttons` 快速生成多个按钮
> `Table.api.formatter.toggle` 快速生成切换按钮

9.复选框
如果我们需要不需要复选框则移除{checkbox: true}即可

10.分类名称(关联搜索出分类表的名称)
这里显示的分类名称是根据分类表关联查询出来的结果,如果我们启用关联查询,我们必须在当前控制器中设置属性protected $relationSearch = true;,同时我们的index方法也需要重写,请参考下方的完整代码中PHP部分。如果我们启用了关联查询,当两个表中的字段有冲突时,我们必须在字段中加上别名。请参考下方的完整代码中JS部分。

11.标志
我们可以使用formatter:Table.api.formatter.flag来渲染标志字段,默认会将数据库的值渲染以下几种颜色

{index: 'success', hot: 'warning', recommend: 'danger', 'new': 'info'}

如果我们需要扩展额外的颜色,则可以使用

custom:{aaa: 'info', bbb:'danger'}

这样当值为aaa时会显示为蓝色,bbb时显示为红色

12.图片和图片组
我们可以使用

formatter:Table.api.formatter.image
formatter:Table.api.formatter.images

以上两种方式来渲染图片或图片组
请注意如果是图片组的情况下,数据值应该是以,进行分隔的

13.开关
我们可以使用formatter:Table.api.formatter.toggle来生成开关组件
默认情况下是根据数据库值1和0来表示开和关
我们可以通过额外的配置和定义开和关,比如

yes: 'open', no: 'close'

则此时会根据数据库值是open还是close来展示开关,
开关在点击的时候默认是只允许修改数据库的status字段的,如果我们开关不是status字段,我们需要在服务端对应的控制器中定义protected $multiFields="id,name,swith";,多个字段以,进行分隔

14.状态渲染
我们可以使用formatter:Table.api.formatter.status来渲染状态
默认根据以下值进行状态的颜色渲染

{normal: 'success', hidden: 'gray', deleted: 'danger', locked: 'info'}

如果我们状态有额外的值,我们可以使用custom来进行扩展显示的颜色,如下

custom: {rejected:'danger', agreed:'success'}

状态渲染显示的文本是根据searchList配置的值进行渲染的

15.自定义按钮
按钮组的功能是根据第8项中的Table.api.formatter.buttons进行生成的,代码如下

 {
    field: 'buttons',
    width: "120px",
    title: __('按钮组'),
    table: table,
    events: Table.api.events.operate,
    buttons: [
        {
            name: 'detail',
            text: __('弹出窗口打开'),
            title: __('弹出窗口打开'),
            classname: 'btn btn-xs btn-primary btn-dialog',
            icon: 'fa fa-list',
            url: 'example/bootstraptable/detail',
            callback: function (data) {
                Layer.alert("接收到回传数据:" + JSON.stringify(data), {title: "回传数据"});
            },
            visible: function (row) {
                //返回true时按钮显示,返回false隐藏
                return true;
            }
        },
        {
            name: 'ajax',
            text: __('发送Ajax'),
            title: __('发送Ajax'),
            classname: 'btn btn-xs btn-success btn-magic btn-ajax',
            icon: 'fa fa-magic',
            url: 'example/bootstraptable/detail',
            confirm: '确认发送',
            success: function (data, ret) {
                Layer.alert(ret.msg + ",返回数据:" + JSON.stringify(data));
                //如果需要阻止成功提示,则必须使用return false;
                //return false;
            },
            error: function (data, ret) {
                console.log(data, ret);
                Layer.alert(ret.msg);
                return false;
            }
        },
        {
            name: 'addtabs',
            text: __('新选项卡中打开'),
            title: __('新选项卡中打开'),
            classname: 'btn btn-xs btn-warning btn-addtabs',
            icon: 'fa fa-folder-o',
            url: 'example/bootstraptable/detail'
        }
    ],
    formatter: Table.api.formatter.buttons
}

按钮配置支持的参数有:

name 按钮唯一标识,其中 add/edit/del/dragsort已经被占用,如果使用将覆盖相应的按钮配置。如果需要按钮按钮显示,我们可以在HTML视图文件的 table添加 data-buttons-标识来根据权限控制显示
text 按钮的文本内容,如果不需要显示文本可忽略,支持 function和 string类型
title 鼠标移上去的标题或 弹窗/选项显示的标题,支持 function和 string类型
icon 按钮的图标,请使用 font-awesome图标库,比如  fa fa-home
classname 按钮的 class, 其中 classname中的 btn-dialog、btn-ajax、btn-addtabs、btn-click,FastAdmin已经为这几个固定的Class注册了事件,所以可以直接使用,如果想要实现其它功能,需要自己手动编写代码绑定事件才可使用。
url 按钮的链接/Ajax事件请求的URL/弹窗链接/选项卡链接,直接 function和 string类型,此链接会自动在链接后添加 ids/{ids}{ids}为当行主键ID,如果需要传递其它字段值,请在URL中使用 {字段名}占位即可
refresh 自动刷新,只针对 btn-ajax事件
confirm 确认框提示文字,配置后会在确认操作再执行对应的事件,只针对 btn-ajax/btn-dialog/btn-addtabs事件
success 事件成功的回调,只针对 btn-ajax事件
error 事件失败的回调,只针对 btn-ajax事件
callback 弹窗回传的回调,只针对 btn-dialog事件,需要在对应打开的页面中使用 Fast.api.close(data);进行回传数据
hidden 是否隐藏按钮,按钮默认显示,支持 function和 bool类型
visible 是否显示按钮,按钮默认显示,支持 function和 bool类型
disable 是否禁用按钮,按钮默认不禁用,支持 function和 bool类型
click 当 classname包含 btn-click时的点击回调事件
extend 按钮扩展信息,可以任意定制按钮的参数,比如我们想在新窗口中打开链接,则配置 extend:' target="_blank"'即可
dropdown 下拉列表分组的名称,当多个按钮需要显示为一级时,该值为显示的文字

16.操作
操作区域默认是排序、编辑、删除这三个按钮,此功能也是根据第8项中Table.api.formatter.operate来实现的。排序按钮只在表中存在weigh字段时才会出现,编辑按钮和删除按钮会根据管理员所拥有的权限进行按需显示。如果我们需要重写编辑(排序、删除)按钮的相关属性,则可以使用buttons来定义编辑(排序、删除)的相关属性。其次Table.api.formatter.operate也支持buttons属性来配置多个其它按钮,如示例图中的详情按钮,配置参数请参考第15.自定义按钮。请参考下方完整代码中JS部分。
如果希望禁用编辑、删除按钮,可以通过修改视图中表格的属性置为空即可。

<table id="table" class="table table-striped table-bordered table-hover table-nowrap"
       data-operate-edit="" 
       data-operate-del="" 
       width="100%">
</table>

17.分页信息
分页信息显示的文字可以通过在表格初始化前定义

$.fn.bootstrapTable.locales[Table.defaults.locale]['formatSearch'] = function (pageFrom, pageTo, totalRows) {
    return '显示第 ' + pageFrom + ' 到第 ' + pageTo + ' 条记录,总共 ' + totalRows + ' 条记录';
};

分页大小或分页大小选项可以在表格初始化时传入以下参数进行配置

pageSize: 10,
pageList: [10, 25, 50, 'All'],

18.翻页信息
翻页信息会根据服务端返回的数据行数自动进行渲染,如果返回的行数不满足分页条件时,此项是不会显示的

完整代码

PHP代码

<?php
namespace app\admin\controller;
use app\common\controller\Backend;
/**
 * 测试管理
 *
 * @icon fa fa-circle-o
 * @remark 此列表是通过php think crud -t test一键生成的针对数据表的查看、添加、编辑、删除、批量修改等功能,只需在设计表时符合FastAdmin相关字段名称、备注要求,即可生成相关的表单组件
 */
class Test extends Backend
{
    protected $model = null;
    protected $relationSearch = true;
    public function _initialize()
    {
        parent::_initialize();
        $this->model = model('Test');
    }
    /**
     * 查看
     */
    public function index()
    {
        if ($this->request->isAjax())
        {
            list($where, $sort, $order, $offset, $limit) = $this->buildparams();
            $total = $this->model
                    ->with("category")
                    ->where($where)
                    ->order($sort, $order)
                    ->count();
            $list = $this->model
                    ->with("category")
                    ->where($where)
                    ->order($sort, $order)
                    ->limit($offset, $limit)
                    ->select();
            $result = array("total" => $total, "rows" => $list, "extend" => ['money' => 1024, 'price' => 888]);
            return json($result);
        }
        return $this->view->fetch();
    }
}

JS代码:

define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) {
 
    var Controller = {
        index: function () {
            // 初始化表格参数配置
            Table.api.init({
                extend: {
                    index_url: 'test/index',
                    add_url: 'test/add',
                    edit_url: 'test/edit',
                    del_url: 'test/del',
                    multi_url: 'test/multi',
                    table: 'test',
                }
            });
 
            var table = $("#table");
 
            //当表格数据加载完成时
            table.on('load-success.bs.table', function (e, data) {
                //这里可以获取从服务端获取的JSON数据
                console.log(data);
                //这里我们手动设置底部的值
                $("#money").text(data.extend.money);
                $("#price").text(data.extend.price);
            });
 
            // 初始化表格
            table.bootstrapTable({
                url: $.fn.bootstrapTable.defaults.extend.index_url,
                pk: 'id',
                sortName: 'weigh',
                columns: [
                    [
                        {checkbox: true},
                        {field: 'id', title: __('Id')},
                        {field: 'admin_id', title: __('Admin_id')},
                        {field: 'category.name', title: __('分类名称'), formatter:Table.api.formatter.search},
                        {field: 'category_id', title: __('Category_id'), visible: false},
                        {field: 'flag', title: __('Flag'), searchList: {"hot": __('Flag hot'), "index": __('Flag index'), "recommend": __('Flag recommend')}, operate: 'FIND_IN_SET', formatter: Table.api.formatter.label},
                        {field: 'genderdata', title: __('Genderdata'), searchList: {"male": __('Genderdata male'), "female": __('Genderdata female')}, formatter: Table.api.formatter.normal},
                        {field: 'title', title: __('Title')},
                        {field: 'image', title: __('Image'), formatter: Table.api.formatter.image},
                        {field: 'images', title: __('Images'), formatter: Table.api.formatter.images},
                        {field: 'createtime', title: __('Createtime'), operate: 'RANGE', addclass: 'datetimerange', formatter: Table.api.formatter.datetime},
                        {field: 'updatetime', title: __('Updatetime'), operate: 'RANGE', addclass: 'datetimerange', formatter: Table.api.formatter.datetime, visible: false},
                        {field: 'weigh', title: __('Weigh'), operate: false, visible: false},
                        {field: 'switch', title: __('Switch'), searchList: {"1": __('Yes'), "0": __('No')}, formatter: Table.api.formatter.toggle},
                        {field: 'status', title: __('Status'), searchList: {"normal": __('Normal'), "hidden": __('Hidden')}, formatter: Table.api.formatter.status},
                        {
                            field: 'buttons',
                            width: "120px",
                            title: __('按钮组'),
                            table: table,
                            events: Table.api.events.operate,
                            buttons: [
                                {
                                    name: 'detail',
                                    text: __('弹出窗口打开'),
                                    title: __('弹出窗口打开'),
                                    classname: 'btn btn-xs btn-primary btn-dialog',
                                    icon: 'fa fa-list',
                                    url: 'example/bootstraptable/detail',
                                    callback: function (data) {
                                        Layer.alert("接收到回传数据:" + JSON.stringify(data), {title: "回传数据"});
                                    },
                                    visible: function (row) {
                                        //返回true时按钮显示,返回false隐藏
                                        return true;
                                    }
                                },
                                {
                                    name: 'ajax',
                                    text: __('发送Ajax'),
                                    title: __('发送Ajax'),
                                    classname: 'btn btn-xs btn-success btn-magic btn-ajax',
                                    icon: 'fa fa-magic',
                                    url: 'example/bootstraptable/detail',
                                    confirm: '确认发送',
                                    success: function (data, ret) {
                                        Layer.alert(ret.msg + ",返回数据:" + JSON.stringify(data));
                                        //如果需要阻止成功提示,则必须使用return false;
                                        //return false;
                                    },
                                    error: function (data, ret) {
                                        console.log(data, ret);
                                        Layer.alert(ret.msg);
                                        return false;
                                    }
                                },
                                {
                                    name: 'addtabs',
                                    text: __('新选项卡中打开'),
                                    title: __('新选项卡中打开'),
                                    classname: 'btn btn-xs btn-warning btn-addtabs',
                                    icon: 'fa fa-folder-o',
                                    url: 'example/bootstraptable/detail'
                                }
                            ],
                            formatter: Table.api.formatter.buttons
                        },
                        {
                            field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate,
                            buttons: [
                                {
                                    name: 'detail',
                                    title: __('详情'),
                                    classname: 'btn btn-xs btn-primary btn-dialog',
                                    icon: 'fa fa-list',
                                    url: 'test/detail',
                                    callback: function (data) {
                                        Layer.alert("接收到回传数据:" + JSON.stringify(data), {title: "回传数据"});
                                    }
                                }],
                            formatter: Table.api.formatter.operate
                        }
                    ]
                ]
            });
 
            // 绑定TAB事件
            $('.panel-heading a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
                var field = $(this).closest("ul").data("field");
                var value = $(this).data("value");
                var options = table.bootstrapTable('getOptions');
                options.pageNumber = 1;
                options.queryParams = function (params) {
                    var filter = {};
                    if (value !== '') {
                        filter[field] = value;
                    }
                    params.filter = JSON.stringify(filter);
                    return params;
                };
                table.bootstrapTable('refresh', {});
                return false;
            });
 
            // 为表格绑定事件
            Table.api.bindevent(table);
        },
        add: function () {
            Controller.api.bindevent();
        },
        edit: function () {
            Controller.api.bindevent();
        },
        api: {
            bindevent: function () {
                Form.api.bindevent($("form[role=form]"));
            }
        }
    };
    return Controller;
});

HTML代码:

<div class="panel panel-default panel-intro">
    <div class="panel-heading">
        {:build_heading(null,FALSE)}
        <ul class="nav nav-tabs" data-field="status">
            <li class="active"><a href="#t-all" data-value="" data-toggle="tab">{:__('All')}</a></li>
            {foreach name="statusList" item="vo"}
            <li><a href="#t-{$key}" data-value="{$key}" data-toggle="tab">{$vo}</a></li>
            {/foreach}
        </ul>
    </div>
    <div class="panel-body">
        <div id="myTabContent" class="tab-content">
            <div class="tab-pane fade active in" id="one">
                <div class="widget-body no-padding">
                    <div id="toolbar" class="toolbar">
                        <a href="javascript:;" class="btn btn-primary btn-refresh" title="{:__('Refresh')}" ><i class="fa fa-refresh"></i> </a>
                        <a href="javascript:;" class="btn btn-success btn-add {:$auth->check('test/add')?'':'hide'}" title="{:__('Add')}" ><i class="fa fa-plus"></i> {:__('Add')}</a>
                        <a href="javascript:;" class="btn btn-success btn-edit btn-disabled disabled {:$auth->check('test/edit')?'':'hide'}" title="{:__('Edit')}" ><i class="fa fa-pencil"></i> {:__('Edit')}</a>
                        <a href="javascript:;" class="btn btn-danger btn-del btn-disabled disabled {:$auth->check('test/del')?'':'hide'}" title="{:__('Delete')}" ><i class="fa fa-trash"></i> {:__('Delete')}</a>
                        <a href="javascript:;" class="btn btn-danger btn-import {:$auth->check('test/import')?'':'hide'}" title="{:__('Import')}" id="btn-import-file" data-url="ajax/upload" data-mimetype="csv,xls,xlsx" data-multiple="false"><i class="fa fa-upload"></i> {:__('Import')}</a>
 
                        <div class="dropdown btn-group {:$auth->check('test/multi')?'':'hide'}">
                            <a class="btn btn-primary btn-more dropdown-toggle btn-disabled disabled" data-toggle="dropdown"><i class="fa fa-cog"></i> {:__('More')}</a>
                            <ul class="dropdown-menu text-left" role="menu">
                                <li><a class="btn btn-link btn-multi btn-disabled disabled" href="javascript:;" data-params="status=normal"><i class="fa fa-eye"></i> {:__('Set to normal')}</a></li>
                                <li><a class="btn btn-link btn-multi btn-disabled disabled" href="javascript:;" data-params="status=hidden"><i class="fa fa-eye-slash"></i> {:__('Set to hidden')}</a></li>
                            </ul>
                        </div>
                        <a class="btn btn-info btn-disabled disabled btn-selected" href="javascript:;"><i class="fa fa-leaf"></i> 获取选中项</a>
                        <a class="btn btn-success btn-singlesearch" href="javascript:;"><i class="fa fa-user"></i> 自定义搜索</a>
                        <a class="btn btn-success btn-change btn-start" data-params="action=start" data-url="example/bootstraptable/start" href="javascript:;"><i class="fa fa-play"></i> 启动</a>
                        <a class="btn btn-danger btn-change btn-pause" data-params="action=pause" data-url="example/bootstraptable/pause" href="javascript:;"><i class="fa fa-pause"></i> 暂停</a>
                        <a href="javascript:;" class="btn btn-default" style="font-size:14px;color:dodgerblue;">
                            <i class="fa fa-dollar"></i>
                            <span class="extend">
                                金额:<span id="money">0</span>
                                单价:<span id="price">0</span>
                            </span>
                        </a>
                    </div>
                    <table id="table" class="table table-striped table-bordered table-hover table-nowrap"
                           data-operate-edit="{:$auth->check('test/edit')}" 
                           data-operate-del="{:$auth->check('test/del')}" 
                           width="100%">
                    </table>
                </div>
            </div>
 
        </div>
    </div>
</div>

感谢博主的详细分析,文章转自:初识fastAdmin表格列表的功能_fastadmin table-CSDN博客

stable diffusion的api参数-附带插件使用

stable diffusion 的 webui中api的使用,包括lora,controlnet、roop、vae等模块。 欢迎留言加群详细交流

{
    "prompt": "(masterpiece, best quality,Refined, beautiful),haruno sakura",
    "negative_prompt": " ((((big hands, un-detailed skin, semi-realistic)))), (((ugly mouth, ugly eyes,The disabled eyes, blurred eyes, missing teeth, crooked teeth, close up, cropped, out of frame))), worst quality, low quality, jpeg artifacts, ugly, duplicate, morbid, mutilated, extra fingers, mutated hands, poorly drawn hands, poorly drawn face, mutation, deformed, blurry, dehydrated, bad anatomy, bad proportions, extra limbs, cloned face, disfigured, gross proportions, malformed limbs, missing arms, missing legs, extra arms, extra legs, fused fingers, too many fingers, long neck,Deforming fingers, incomplete fingers, extra fingers,Ugly face",
    "override_settings": {
        "sd_model_checkpoint": "MXCFSuper_Counterfeit/mxcfSuperCounterfeit_v10.safetensors [56c0585d87]",
        "sd_vae": "YOZORA.vae.pt"
    },
    "clip_skip": 2,
    "denoising_strength": 0.5,
    "seed": -1,
    "batch_size": 1,
    "n_iter": 1,
    "steps": 25,
    "cfg_scale": 7,
    "restore_faces": False,
    "sampler_index": "DPM++ SDE Karras",
    "resize_mode": 1, # "mask_blur": 10, # "tiling": False, # "eta": 0, # "script_args": [], # "inpainting_fill": 1, # "inpaint_full_res": True, # "inpaint_full_res_padding": 32, # "inpainting_mask_invert": 1,
    "alwayson_scripts": {
        "other plugin": {
            "args": [arg1, arg2
            ]
        } "ControlNet": {
            "args": [
                {
                    "enabled": True,
                    "input_image": "",
                    "mask": None,
                    "module": "canny",
                    "model": "control_sd15_canny [fef5e48e]",
                    "weight": 1,
                    "invert_image": False,
                    "resize_mode": 1,
                    "rgbbgr_mode": False,
                    "lowvram": False,
                    "processor_res": 512,
                    "threshold_a": 100,
                    "threshold_b": 200,
                    "starting_control_step": 0,
                    "ending_control_step": 1, # "guidance": 1, # "guidance_start": 0, # "guidance_end": 1,
                    "guessmode": False
                }
            ]
        }
    }
}

参数解释:

模型:MXCFSuper_Counterfeit

VAE:none

Clip skip:2 

Prompt:

Negative Prompt:””

Resize mode:Just resize

Sampling method:DPM++ SDE Karras

Sampling steps:25

Restore faces:flase

Width:所传图片宽度

Height:所传图片高度

Batch count:1

Batch size:1

CFG Scale:5

Denoising strength:0.5

Seed:-1

ControlNet:Enable

Control Type:Canny

Preprocessor:Canny

Model:control_sd15_canny

Control Weight:1

Starting Control Step:0

Ending Control Step:1

Preprocessor Resolution:512

Canny Low Threshold:100

Canny Hight Threshold:200

Control Mode:Balanced

Resize Mode:Crop and Resize

Script:none

腾讯云安装stable diffusion webui

安装项目中的提示操作:GitHub – AUTOMATIC1111/stable-diffusion-webui: Stable Diffusion web UI

遇到的问题:

  1. github中clone项目的时候慢:
  2. 安装torch的时候源慢:
    • 安装的时候等一会,一般是前面阶段比较慢,到后面速度就会上来。
    • 可以在launch.py中将对应的源替换掉,使用清华的源。
  3. 一些缺失的包:
    • ERROR: Cannot activate python venv
    • python3 -m venv venv/
      1. 安装TCMalloc
        • apt install libgoogle-perftools-dev
  4. 服务器重启后找不到显卡驱动,报错 torch is not able to use gpu
    • apt update 更新的时候 内核的header没安装成功,重启了服务器,造成显卡驱动没有正常运行 重新安装了一下 kernel header
    • sudo apt install linux-headers-$(uname -r)
  5. 无法使用公网访问:
    • Could not create share link. Please check your internet connection or our status page: https://status.gradio.app
      • 没解决,并且sd默认的公网服务并不稳定。  使用nginx反向代理7860端口解决
      • 换海外服务器
  6. ERROR: Cannot activate python venv, aborting…
    • python3 -c ‘import venv’ #should not return any errors
    • python3 -m venv venv/ #should populate the directory
  7. nginx做反向代理,需要增加socket支持:
    • location / {
    • proxy_pass http://127.0.0.1:7860;
    • proxy_http_version 1.1;
    • proxy_set_header Upgrade $http_upgrade;
    • proxy_set_header Connection “Upgrade”;
    • proxy_read_timeout 300s;
    • proxy_connect_timeout 300s;
    • }
  8. 运行: ./webui.sh –share –enable-insecure-extension-access

使用cloudflare代理flask启用https服务

问题1:使用cloudflare的dns回源服务器的时候,出现了http和https不断反复重定向

问题2:  flask只能启用http服务,需要启用https

  • 使用lnmp vhost add 添加域名,配置ssl证书
  • pip install gunicorn
  • 新建文件 gunicorn_start.sh(解决问题2),运行sh gunicorn_start.sh
#!/bin/bash
 
# 定义Flask应用程序的名称和入口文件名
APP_NAME=app
APP_ENTRYPOINT=app:app
 
# 定义SSL证书和私钥文件的路径
CERT_FILE=/path/to/cert.pem
KEY_FILE=/path/to/key.pem
 
# 启动Gunicorn
gunicorn $APP_ENTRYPOINT \
  --bind 0.0.0.0:443 \
  --certfile $CERT_FILE \
  --keyfile $KEY_FILE \
  --workers 4 \
  --worker-class gthread \
  --threads 2 \
  --timeout 120 \
  --log-level=info \
  --access-logfile=- \
  --error-logfile=-
  •  nginx  配置
server
    {
        listen 443 ssl http2;
        #listen [::]:443 ssl http2;
        server_name your-site ;
        index index.html index.htm index.php default.html default.htm default.php;
        root  /home/wwwroot/your-site;
 
        ssl_certificate /usr/local/nginx/conf/ssl/your-site/fullchain.cer;
        ssl_certificate_key /usr/local/nginx/conf/ssl/your-site/your-site.key;
        ssl_session_timeout 5m;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
        ssl_prefer_server_ciphers on;
        ssl_ciphers "TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-128-GCM-SHA256:TLS13-AES-128-CCM-8-SHA256:TLS13-AES-128-CCM-SHA256:EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5";
        ssl_session_cache builtin:1000 shared:SSL:10m;
        # openssl dhparam -out /usr/local/nginx/conf/ssl/dhparam.pem 2048
        ssl_dhparam /usr/local/nginx/conf/ssl/dhparam.pem;
 
 
        # Deny access to PHP files in specific directory
        #location ~ /(wp-content|uploads|wp-includes|images)/.*\.php$ { deny all; }
 
        location / {
                proxy_pass https://127.0.0.1:5000;
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
        access_log  /home/wwwlogs/your-site.log;
 
    }
  • cloudflare找到对应的域名,点击左侧的 “SSL/TLS”。 将“Your SSL/TLS encryption mode ” 配置成FULL或者FULL(Strict) (否则不支持https,解决问题1)

手把手教你国内注册ChatGPT Plus 【典藏版】

一、ChatGPT Plus

升级到付费版的ChatGPT Plus好处自然不用说,懂的都懂。比如稳定,无字数限制,不会有错误等等。

本文就分享一下本人(以及若干ChatGPT Plus爱好者+群友)亲测有效的ChatGPT Plus付费版升级流程。注册门槛说实话有点高,不过总结起来其实就下面4个步骤:

1.png

这里简单说,欧易是港股上市,国内最大的交易所,Depay是最大的虚拟信用卡公司。

二、实操步骤

要完成上述4个步骤,你需要提前准备好:

  1. 注册1个可用的ChatGPT账号
  2. 注册1个虚拟交易平台欧易账号(没得选,国内安全的只有它)
  3. 申请1张虚拟信用卡(选Depay,群里小伙伴都是用它)
  4. 能正常访问ChatGPT的科学上网条件(一定要选美国的代理节点)

1、申请ChatGPT账号

这一步网上有很多详细的教程,我这里就不细说了。还没有自己的ChatGPT账号的,先参照https://sms-activate.org/cn/info/ChatGPT 一步一步做,申请一个属于自己的ChatGPT,这个教程注册+接验证码都有了,国内的手机号也可以完成注册。

照着做就行,只有先搞定ChatGPT账号,才能在此基础上升级到ChatGPT Plus。

已经有ChatGPT账号的,直接进入第2步,走起!

2、申请欧易账号完成USDT充值

因为Depay不接受人民币直接充值,所以我们必须借助交易所平台,来完成

人民币—USDT—USD美元的兑换过程,等Depay账户里有USD美元了再充值。这里,对USDT不熟悉的朋友我说一下,USDT是虚拟货币泰达币,跟USD锚定的,安全不用担心。

关于交易所,咱国内用户,受前两年国家整顿的政策影响,当下国家支持并且靠谱的大交易所目前就仅剩下欧易一家独大了,咱没得选,乖乖注册一个欧易账号就好。

点击这里–>跳转官网注册欧易账号

等待欧易账号注册好,下载并安装APP,安装过程中如果系统提示有安全风险,不必理会,对于虚拟货币,系统都会误报,咱们这是正规官网下载的,哪来的风险,忽略就好。

耐心等待欧易App安装成功,点击App首页——我要买币——快捷买币——选USDT——购买至少23USDT(大概¥200)——支持支付宝、微信或者银行卡购买。

做完上面这一步,就完成人民币——USDT的兑换。

这里,我多买点,买36USDT,大概250人民币。

2.png

3、申请虚拟信用卡Depay

  1. 什么是Depayundefined首先,ChatGPT要求必须美国的信用卡,咱们国内的双币卡、全币卡都不能用。undefined不用说,对于国内没有美国当地信用卡的小伙伴,肯定选赫赫有名的Depay美国虚拟信用卡。
  2. 注册Depay账号undefined点此注册Depay账号,可以用邮箱或者手机号,我本人选的谷歌邮箱注册,如果验证码没收到很可能在垃圾箱里。账号注册成功后,会让你下载它们的App安装,苹果手机需要登录海外的Apple账号,安卓手机可以直接下载apk安装,我下载的是depay1.2.4.apk版本。耐心等待APP安装完毕,用刚刚注册的账号和密码登录Depay。
  3. 申请第一张卡undefined点击界面左上角的“申请卡”开通虚拟信用卡,开卡的时候可以选0开卡费的,也可以选10USDT开卡费的,区别是0开卡费的需要你完成KYC认证,通俗点说就是需要你上传身份证(国内身份证没问题)认证,建议开通0开卡费的长期使用。undefined卡开通后,可以往Depay里充值USDT ,这一步在接下去的第4小章节会讲到,需要用到前面注册的欧易账号来充值USDT。
3.png

4、给钱包充值USDT

1、 打开Depay App钱包,找到钱包——USDT——充币——复制你的充值地址,确认屏幕上显示主网是TRC20,

充值地址千万不要复制错,比如我的Depay钱包的USDT充值地址是TKeiEjFBDyJTAb89YhFDQCyFfLjiZJt55Z。

复制

4.png

2、 打开上面第2步注册的欧易App,找到首页——资产——提币——USDT——链上提币。

提币地址填Depay钱包里的充值地址,这里我填TKeiEjFBDyJTAb89YhFDQCyFfLjiZJt55Z,

提币网络选TRC20 (千万不能选错,否则到不了账),

数量选大于23USDT就行,够充值1个月ChatGPT Plus会员就行。

提交,等待到账。

5.png

3、欧易提现到Depay成功后,点击Depay App钱包——兑换,将所有的USDT都兑换成USD美元

6.png

4、点击Depay App首页的To Card,将兑换的美元存入卡中,到此,Depay充值大功告成。

📢📢📢注意

需要注意的是,新注册的欧易用户默认完成身份认证后,需要等待24小时才可以提现,如果你着急提现到Depay,你也可以私信找我代充,按照汇率1:8收点劳务费。一般不是很急的话建议24小时就行,不必花这冤枉钱。

三、开通ChatGPT Plus

我们已经在第3步中拥有了一张属于自己的虚拟信用卡(其实相当于借记卡,不可透支),并且往里面充了20多美刀,够我们订阅1个月ChatGPT Plus了。

登录ChatGPT, 左下角找到升级Plus的选项——Upgrade to Plus

7.png

一些群友反馈没有出现这个升级的选项,记得把IP切换到美国再重新登陆,现阶段只有美国的IP才会有这个选项,(升级的时候需要美国IP,升级完毕后不要求)。

另外,切记切记——

  1. 科学上网,一定要用美国IP
  2. 浏览器开启无痕模式
  3. 账单地址用美国地址生成器生成
  4. 如果1、2都做了还是失败,那么尝试清空浏览器缓存,重新登录ChatGPT再尝试。如果还是不行,那么建议更换你目前在用的代理节点再试,直到成功。

关于代理

代理一定要用美国的IP,如果你不确定自己的IP是不是美国的,http://en.ipip.net/ 查看。不要用那种很多人使用的代理,容易失败。

关于账单地址

理论上随便填都行,你可以网上搜美国地址生成器,直接生成一个免税州的账单地址:

8.png

请一定要用美国IP访问,否则可能会遇到如下报错:

11.png

四、ChatGPT Plus初体验

看到如下PLUS的尊贵标识,就说明你已经成功开通ChatGPT Plus了。

只能说,这钱花的值,你将拥有了AI的丝滑体验。

9.png

每个月大概不到¥150,也就3杯星巴克的钱,换来的是一个高效的信息获取渠道,不亏,是一个跨时代的生产力。

至此,恭喜您,已经成为了尊贵的ChatGPT Plus用户,成为全球走在时代前沿的人了。从现在起,访问ChatGPT Plus就拥有Default和Legacy双模型回答,以及快速、稳定的AI回复。

10.png

五、常见问题&解决

这里汇总了群友最常遇到的一些问题及解决办法如下——

  1. 如何取消ChatGPT Plus的自动订阅?
> 上面说过,我们的Depay信用卡其实没有透支功能,只是相当于借记卡,理论上说只要你不往卡里充钱,其实不必担心下个月被扣款。不过,保险起见,你还是可以取消自动订阅,方法是:  
> 打开ChatGPT首页并登录——左下角——My Account——Manage My Subscription——Cancel Plan

复制

  1. ChatGPT Plus中的default mode和legacy mode有什么区别?
> default mode就是Turbo mode,它会更有情感和活力,会有趣一些,不过回答上偏更加简洁,省去了之前legacy mode一些细节。  
> legacy mode则更适合学术论文,不像Turbo Mode回答那么大众,适合科研,论文。  
> 更详细的比较可以参考:<https://www.reddit.com/r/ChatGPT/comments/111skny/the_differences_between_default_and_legacy_models/>

复制

  1. 为什么升级到ChatGPT Plus需要这么麻烦?
> 这个问题归根结底是因为openAI不支持PayPal充值,大家没事就写 e-mail给openai的ceoSam Altman(国人喊他奥特曼),让他早点支持支持payPal吧。

复制

  1. 升级ChatGPT Plus每个月$20值不值?
> 这是一个仁者见仁智者见智的问题,你觉得值它就值,你觉得不值,就尝试下取消续费就好。不过,应该没人会拒绝更优越的生产力吧?

github连接超时(不能push,不能pull)

git pull 或者git push的时候,提示:

kex_exchange_identification: Connection closed by remote host
Connection closed by 127.0.0.1 port 22
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
  1. 使用命令:ssh -T git@github.com
    1. 返回结果:Hi developer! You’ve successfully authenticated, but GitHub does not provide shell access.
    2. 表明没有问题
  2. 使用代理:
#只对github.com
git config --global http.https://github.com.proxy socks5://127.0.0.1:1080

#取消代理
git config --global --unset http.https://github.com.proxy

还是同样的问题。

3. 将ssh的22端口改为使用443

在等待git pull命令超时之后报出了类似: ssh: connect to host github.com port 22: Connection timed out的错误!

原因是: ssh 阻塞了22端口!

解决方法: 修改 ssh 的配置文件

关于修改配置,存在两种解决方法:

/etc/ssh/ssh_config 中修改全局配置
在用户主目录下.ssh/中添加配置文件
这里选择的后者:

cd ~/.ssh/
vi config

# 在config中添加下面内容
Host github.com  
User git  
Hostname ssh.github.com 
PreferredAuthentications publickey  
IdentityFile ~/.ssh/id_rsa 
Port 443
即: 使用https的443端口进行访问!