精华内容
下载资源
问答
  • 大佬们请问平方差函数是什么这个有什么用这个表达的啥意思😳<img alt="" height="602" width="800" src="https://userblink.csdnimg.cn/20210426/gao_0111/pic/164dfe4911447ae5fb42ccba96e6b8a1-0.jpg" />
  • int main(){ const int p=6; int * q=(int* ) & p ; *q=7; cout; cout*q; } 输出结果: 0x6dfe98 0x6dfe98 7 6 两个变量的地址都一样的,为什么值不一样啊
  • lesshat-selector { -lh-property... } 这个是什么用处? **lesshat-selector { -lh-property: 0; } ** ::selection{color: #dfe1e8; background: #5b90bf} ::-moz-selection{color: #dfe1e8; background: #5b90bf; }
  • <div>dsfe<strong>dsfe<span>dfe</span></strong> <div>dsfe<strong>dsfe<span>dfe</span></strong> <div>dsfe<strong>dsfe<span>dfe</span></strong> <div>dsfe<strong>dsfe<span>dfe</span></strong> <div>...
  • <div><h4>http和https压测出来QPS相差几倍,大家知道是什么问题吗? 服务器<code>4核16G,同一个接口地址,把https<code>配置在NGINX和配置在Laravel-s里面结果都是一样的 <pre><code># http QPS 454 # ...
  • 什么是调整后的R方

    千次阅读 2018-08-08 17:16:00
    当给模型增加自变量时,复决定系数也随之逐步增大,当自变量足够多时总会得到...R2=SSR/SST=1-SSE/SSTRa2=1-(SSE/dfE)/(SST/dfT) 即: Ra2 = 1- (SSE/(n-p-1)) / (SST/(n-1)) 转载于:https://www.cnblogs.com...

    当给模型增加自变量时,复决定系数也随之逐步增大,当自变量足够多时总会得到模型拟合良好,而实际却可能并非如此。于是考虑对R2进行调整,记为Ra2,称调整后复决定系数。
    R2=SSR/SST=1-SSE/SST
    Ra2=1-(SSE/dfE)/(SST/dfT)

    即:

     Ra2 = 1-   (SSE/(n-p-1)) / (SST/(n-1))

    转载于:https://www.cnblogs.com/lantingg/p/9444076.html

    展开全文
  • <p><img alt="image" src="https://user-images.githubusercontent.com/14103319/34460092-6dfe5bee-ee3f-11e7-912d-c1747fd71599.png" /></p> 边沿触发器的作用就是只有当CLK端输入从0变到1时,数据端D的输入...
  • 指针

    2021-04-20 21:02:16
    指针♂引用什么是指针普通指针指针作为形参什么是引用引用的作用指向引用的指针 什么是指针 普通指针 首先先理解变量 int a=1; printf("%p\n",&a); printf("%d\n",a); 这里给大家补充一个知识点,%p查看地址 ...

    1.什么是指针

    普通指针

    首先先理解变量

    int a=1;
    printf("%p\n",&a);
    printf("%d\n",a);
    

    这里给大家补充一个知识点,%p是查看地址

    006dfe9c
    1

    这里的006dfe9c是变量a的地址,而1是这个地址(006dfe9c)存的值
    在这里插入图片描述
    我们讲繁杂的地址值用抽象的a来表示,而编译器会自动还原a->006dfe9c

    那么,指针呢?
    这里说明一点,*有取地址的做用,称为升维。&在此处有取地址的作用,称为降维。
    可见,指针p具有自己的地址,而指针p地址中存的地址,可以由用户来修改,p=&a就是取a的地址,赋值给p,如图

    int* p=NULL;
    printf("&p=%p\n",&p);
    printf("p=%d\n",p);
    p=&a;
    printf("&p=%p\n",&p);
    printf("p=%p\n",p);
    printf("*p=%d\n",*p);
    

    &p=006dfe98
    p=0
    &p=006dfe98
    p=006dfe9c
    *p=1

    指针作为形参

    #include<bits/stdc++.h>
    void example(int *q){
    	printf("q=%d\n",*q);
    	printf("&q=%p\n",&q);
    }
    int main(){
    	int a=1;
    	int *p=NULL;
    	p=&a;
    	printf("p=%d\n",*p);
    	printf("&p=%p\n",&p);
    	example(p);
    } 
    

    先来看结果

    p=1
    &p=006dfe98
    q=1
    &q=006dfe80

    我们发现,p,q的值是一样的,为什么p,q自身的地址不一样呢?因为函数传递的时候是:"值传递"而非“地址传递”,如图
    在这里插入图片描述

    2.什么是引用

    int a=1;
    int &b=a;
    printf("%d\n",b); 
    printf("%p\n",&a);
    printf("%p\n",&b);
    

    1
    006dfe98
    006dfe98

    引用符号是&,这里是b其实就是a 的别名,如果a是某个人的大名,那么b就是某个人的小名
    所以b的值就是a的值,b的地址就是a的地址
    在这里插入图片描述
    看,就是把b挂了上去!
    但是,不能再用b引用别人了,意思是这个小名是a独有的,别人不能用这个小名
    在这里插入图片描述
    显然这个操作是不合法的

    引用的作用


    我们知道,函数值传递不会改变原来的地址内存的值
    而引用可以直接把地址传进去, 如图
    在这里插入图片描述

    3.指向引用的指针

    除了引用,指针也可以交换a,b的值,如图
    在这里插入图片描述


    指针传给函数里面,实质上是把指针指向的地址(指针的内容)传进去,那么只能修改这个地址单元里面的东西,而不能修改这个地址
    而引用,是这个变量的地址,那么指向引用的指针,就可以修改,指针指向的地址,也可以修改指向的地址里面的地址(内容)
    如何理解上述内容呢,来看实例
    在这里插入图片描述
    这就是指向引用的指针(*&)的好处(既可以修改存储的地址,又可以修改存储地址的内容),为什么这样说呢,从图中,我们可以看到p1,p3的自身的地址是不会变的,但是,
    p1,p3其中存的地址(&a,&c),是可以被改变的
    解释:如果单用指针作为形参,那么传进去的是其中的地址,只能修改p1中地址的内容(&a) ,意思就是只能对a的值修改,而如果想让p1指向b,指向c,在指针作为形参中是做不到的
    而为什么现在可以修改p1存的内容了呢,想让p1=&a,想让p1=&b,都可以,这是因为引用,正因为有了引用,函数形参传进去的是p1这个单元的地址,而非这个单元存的地址

    那么可以会有很多同学问了,*&我怎么没见过,用在哪里,就目前我见过的而言,用在链表,如图

    在这里插入图片描述
    这里的形参是指针,红色箭头上一句是合法的,而红色箭头那一句是非法的
    taillist->next=newlist这个操作,其内部操作是,用tailist里面存的地址,取出存的地址的next单元进行赋值操作
    而talilist=taillist->next这个操作,其内部操作是,修改"taillist"(假)里面存的地址,但是这个修改是假的,因为函数传递的时候是:"值传递"而非“地址传递”,即函数体中的taillist的本身地址,和函数体外面的taillist的本身地址,是不一样的,一样的是taillist里面指向的地址,如有不懂,请回头看上文指针作为形参的解释

    如果本文有错误,欢迎提出

    展开全文
  • 是什么 计划是实现一个用于通信的rx dsp库,其中包含数据产生、信号同步提取、均衡算法和判决与误码计算等代码。 尚未完成 该readme的编写 新的均衡算法的实现 Linear DFE Volterra DFE 一些Machine Learning算法 ...
  • 在github上下载源码导入eclipse,在命令行进入源码的api文件夹,运行make install,安装依赖库和api本身,但是有一个报错, 报错内容: Cloning ...请问是什么原因造成的错误,并且怎么解决这个问题
  • DWARF, 说不定你也需要它哦

    千次阅读 2018-12-27 15:23:11
    https://www.jianshu.com/p/20dfe4fe1b3f DWARF 一种调试信息格式,通常...什么是 DWARF ? DWARF 第一版发布于 1992 年, 主要为UNIX下的调试器提供必要的调试信息,例如PC地址对应的文件名及行号等信息,以方...

    https://www.jianshu.com/p/20dfe4fe1b3f

    DWARF 是一种调试信息格式,通常用于源码级别调试
    相关资料比较琐碎, 整理给大家, 希望大家可以用得上

    如没有特殊说明, 命令执行环境为 OS X

    什么是 DWARF ?

    • DWARF 第一版发布于 1992 年, 主要是为UNIX下的调试器提供必要的调试信息,例如PC地址对应的文件名及行号等信息,以方便源码级调试
    • 其包含足够的信息以供调试器完成特定的一些功能, 例如显示当前栈帧(Stack Frame)下的局部变量, 尝试修改一些变量, 直接跳到函数末尾等
    • 有足够的可扩展性,可为多种语言提供调试信息: 如: Ada, C, C++, Fortran, Java, Objective C, Go, Python, Haskell ...
    • 除了编译/调试器外,还可用于从运行时地址还原源码对应的符号|行号的工具(如: atos)

    目前 DWARF 已经在类UNIX系统中逐步替换 stabs(symbol table strings) 成为主流的调试信息格式。
    使用GCC或者LLVM系列编译器都可以很方便生成DWARF调试信息。

    下面是其发展历史:

    DWARF版本 年份 组织 详情
    DWARF1 1992 Unix SVR4, PLSIG, UnixInternational 贝尔实验室 1988 年开发用于SVR4, 用于C compiler & SDB, PLSIG 和 Unix International在1992年为其编写了文档, 缺点: 结构不紧凑
    DWARF2 1993 PLSIG PLSIG 做了一些优化(主要是减少调试信息大小),于1993年发布了DWARF 2 草案。但是由于摩托罗拉的 88000 处理器出现了一些严重故障,导致了一家名为 Open88 的公司破产, 而 Open88 公司是 PLSIG 和 UnixInternational 的金主, 随后这两个组织随即解散, DWARF 2 正式标准就从未发布。
    DWARF3 2005 Free Standards Group 因为在 HP/Intel IA­64 architecture 架构及 C++ ABI 方面有更好的表现, Free Standards Group 在 2003 年完成了草案并在2005年发布了正式标准
    DWARF4 2010 DWARF Debugging Format Committee Free Standards Group 和 Open Source Development Labs 在 2007 年合并为了著名的 Linux Foundation, DWARF委员会随后以独立方式存在并创建了网站 dwarfstd.org, 进行了一系列的更新后(支持LVIM, 对 Type Description存储的优化等),于2010 年发布 DWARF4
    DWARF5 2017 DWARF Debugging Format Committee 在经过六年的开发后, DWARF委员会于 2017 年发布了 DWARF5 标准, 主要特性有: 更优的数据压缩, 调试信息从可执行文件的分离, 对宏定义有更好支持, 更快的搜索符号(symbol)

    下面列出DWARF的一些竞品,方便大家更了解调试格式的发展

    格式 年份 典型使用环境
    stabs (symbol table strings) 1981 广泛使用于 Unix 环境, 目前已经逐步被 DWARF 替换
    COFF (Common Object File Format) 1983 UNIX System V(AT&T), AIX(IBM, XCOFF), DEC、SGI(ECOFF)
    IEEE­695 1990 虽是 IEEE 标准, 但是支持少数几种处理器架构, 目前已经基本消亡
    PE­COFF (PE/COFF) 1995(?) Windows PE, Windows NT, COFF 最流行的变种
    OMF (Object Module Format) 1995(?) CP/M, DOS, OS/2, embedded systems
    PDB(Program database) ? Windows, Microsoft Visual Studio 的默认调试格式

    我们为什么需要 DWARF ?

    上面我们提到DWARF主要为调试器(debugger)服务,我们通过实现一个调试器Demo,帮助大家了解整个技术链。

    首先,我们看下一般调试器的样子:

     

    image.png

    下面的例子源于 How debuggers work

    这个简单的调试器只完成一个功能: 打印被调试程序运行时执行的所有指令

    下面的例子使用了 Linux ptrace系统调用, 虽然我很想用 Mac 做演示, 但是 ptrace(OS X) 在Mac上已经被阉割了, 缺少 GETREGS 这种关键的 ptrace 功能,
    而使用 thread_get_state() 又过于复杂, 所以 ...

    体验编写一个调试器-Demo

    • 启动 Linux 容器(如果本地没有Linux环境)
    docker run --cap-add=SYS_PTRACE --security-opt seccomp=unconfined \
        -it harisekhon/ubuntu-dev /bin/bash
    
    • 创建工作目录, 创建 被调试程序hello.c
    mkdir ptrace-example-mac; cd ptrace-example-mac
    
    cat > hello.c <<EOF
    #include <stdio.h>
    
    int main() {
        printf("Hello, world!?\n");
        return 0;
    }
    EOF
    
    • 创建调试器Demo main.c
    cat > main.c <<EOF
    #include <stdio.h>
    #include <stdarg.h>
    #include <stdlib.h>
    #include <signal.h>
    #include <sys/types.h>
    #include <sys/ptrace.h>
    #include <sys/wait.h>
    #include <sys/user.h>
    #include <unistd.h>
    
    
    void procmsg(const char* format, ...);
    void run_target(const char* programname);
    void run_debugger(pid_t child_pid);
    
    int main(int argc, char** argv)
    {
        pid_t child_pid;
    
        if (argc < 2) {
            fprintf(stderr, "Expected a program name as argument\n");
            return -1;
        }
    
        child_pid = fork();
        if (child_pid == 0)
            run_target(argv[1]);
        else if (child_pid > 0)
            run_debugger(child_pid);
        else {
            perror("fork");
            return -1;
        }
    
        return 0;
    }
    
    /* Print a message to stdout, prefixed by the process ID
    */
    void procmsg(const char* format, ...)
    {
        va_list ap;
        fprintf(stdout, "[%d] ", getpid());
        va_start(ap, format);
        vfprintf(stdout, format, ap);
        va_end(ap);
    }
    
    
    void run_target(const char* programname)
    {
        procmsg("target started. will run '%s'\n", programname);
    
        /* Allow tracing of this process */
        if (ptrace(PTRACE_TRACEME, 0, 0, 0) < 0) {
            perror("ptrace");
            return;
        }
    
        /* Replace this process's image with the given program */
        execl(programname, programname, (char *)0);
    }
    
    
    void run_debugger(pid_t child_pid)
    {
        int wait_status;
        unsigned icounter = 0;
        procmsg("debugger started\n");
    
        /* Wait for child to stop on its first instruction */
        wait(&wait_status);
    
        while (WIFSTOPPED(wait_status)) {
            icounter++;
            struct user_regs_struct regs;
            ptrace(PTRACE_GETREGS, child_pid, 0, &regs);
            unsigned instr = ptrace(PTRACE_PEEKTEXT, child_pid, regs.rip, 0);
    
            procmsg("icounter = %u.  IP = 0x%08x.  instr = 0x%08x\n",
                    icounter, regs.rip, instr);
    
            /* Make the child execute another instruction */
            if (ptrace(PTRACE_SINGLESTEP, child_pid, 0, 0) < 0) {
                perror("ptrace");
                return;
            }
    
            /* Wait for child to stop on its next instruction */
            wait(&wait_status);
        }
    
        procmsg("the child executed %u instructions\n", icounter);
    }
    EOF
    
    • 编译
    gcc -O0 hello.c -o hello    # 编译被调试程序
    gcc main.c -o ptrace-example-linux    # 编译调试器 demo
    

    编译完成后工作目录如下:

    root@9e0370a08026:/ptrace-example-mac# ll
    total 40
    drwxr-xr-x 2 root root 4096 Apr 21 05:19 ./
    drwxr-xr-x 1 root root 4096 Apr 21 05:14 ../
    -rwxr-xr-x 1 root root 8600 Apr 21 05:18 hello*
    -rw-r--r-- 1 root root   81 Apr 21 05:17 hello.c
    -rw-r--r-- 1 root root 1888 Apr 21 05:17 main.c
    -rwxr-xr-x 1 root root 9248 Apr 21 05:19 ptrace-example-linux*
    
    • 执行
    ./ptrace-example-linux hello    # 执行 Hello 并打印Hello运行过程中执行的指令数
    

    运行结果如下:

    ...
    [60] icounter = 141731.  IP = 0x3818271a.  instr = 0x00e7b841
    [60] icounter = 141732.  IP = 0x38182720.  instr = 0x00003cbe
    [60] icounter = 141733.  IP = 0x38182725.  instr = 0x0f6619eb
    [60] icounter = 141734.  IP = 0x38182740.  instr = 0x44d78948
    [60] icounter = 141735.  IP = 0x38182743.  instr = 0x0fc08944
    [60] icounter = 141736.  IP = 0x38182746.  instr = 0x3d48050f
    [60] the child executed 141736 instructions
    

    调试器总结

    从上面的调试器Demo执行的结果及源码看, 调试器从 ptrace 系统调用拿到的信息有

    • IP: 指令指针寄存器, 表示CPU当前执行的指令在内存中的地址
    • instruction: 当前CPU执行的指令内容
    • regs: 部分寄存器
    • PEEKTEXT: 可在程序内存空间取值
    • ...

    但从我们平时使用的调试器提供给我们更多的信息:

    • 当前程序执行指令对应于源码的文件及行号
    • 当前程序栈帧(stack frame|activation record) 下的局部变量
    • ...

    调试器如何从一些十分基础的信息,例如 IP(指令地址), 呈现给我们如此丰富的调试信息呢?

    那便我们为什么需要 DWARF, 其提供了程序运行时信息(Runtime)到源码信息的映射(Source File)

    IP|regs|address      >>>  Source File 
    (Runtime)           DWARF    
    

    认识 DWARF

    使用 GCC 生成 DWARF 调试信息

    认识 DWARF 的第一步便是如何生成 DWARF 信息, 所幸这个过程非常简单

    • 对于 GCC 及 CLang 编译器, 使用参数 -gdwarf-4 即可生成 DWARF4 调试信息

    我们使用一个名为 foo.c 的示例程序来演示 生成并探索 DWARF 内容

    • 创建工作目录及 foo.c 文件
    mkdir show-dwarf; cd show-dwarf;
    
    cat > foo.c <<EOF
    int foo(int a, int b) {
        int c;
        static double d = 5.0;
        c = a + b;
        return c;
    }
    
    int main() {
        int r;
        r = foo(2, 3);
        return 0;
    }
    EOF
    
    • 使用 GCC 编译并生成 DWARF4 编译信息
    gcc -O0 -gdwarf-4 foo.c -o foo
    

    编译完成后, 会发现多了 foo.dSYM 的目录, 当前工作目录文件列表如下:

    masterkang: ~/Documents/show-dwarf > ll
    total 32
    -rwxr-xr-x  1 masterkang  staff  8728  4 21 13:58 foo
    -rw-r--r--  1 masterkang  staff   153  4 21 13:57 foo.c
    drwxr-xr-x  3 masterkang  staff    96  4 21 13:58 foo.dSYM
    
    • 使用 lldb 调试 foo 并观察 foo.dSYM 是否起作用

      1. lldb foo 启动 lldb 并设置被调试程序为 foo
      2. 在 lldb 交互命令输入: b foo 设置函数 foo 为断点
      3. 在 lldb 交互命令输入: run 开始运行被调试程序

      调试器稍后之后会在 foo 函数停下来并且打印出对应的源码位置

    masterkang: ~/Documents/show-dwarf > PATH=/usr/bin lldb foo
    (lldb) target create "foo"
    Current executable set to 'foo' (x86_64).
    (lldb) b foo
    Breakpoint 1: where = foo`foo + 10 at foo.c:4, address = 0x0000000100000f6a
    (lldb) run
    Process 96385 launched: '/Users/masterkang/Documents/show-dwarf/foo' (x86_64)
    Process 96385 stopped
    * thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
        frame #0: 0x0000000100000f6a foo`foo(a=2, b=3) at foo.c:4
       1    int foo(int a, int b) {
       2        int c;
       3        static double d = 5.0;
    -> 4        c = a + b;
       5        return c;
       6    }
       7
    Target 0: (foo) stopped.
    (lldb)
    
    • 进入到 foo.dSYM 目录并且找到调试信息文件 foo
    cd foo.dSYM/Contents/Resources/DWARF
    
    masterkang: ~/Documents/show-dwarf/foo.dSYM/Contents/Resources/DWARF > ll
    total 24
    -rw-r--r--  1 masterkang  staff  9166  4 21 13:58 foo
    
    • 使用 file 命令查看 foo 文件描述
    masterkang: ~/Documents/show-dwarf/foo.dSYM/Contents/Resources/DWARF > file foo
    foo: Mach-O 64-bit dSYM companion file x86_64
    

    从描述看, 可以看到这是一个 Mach-O 文件

    • 既然是 Mach-O 文件, 使用 size 命令查看 foo 可执行文件包含的 Segment 和 Section
    masterkang: ~/Documents/show-dwarf/foo.dSYM/Contents/Resources/DWARF > size -x -m -l foo
    Segment __PAGEZERO: 0x100000000 (vmaddr 0x0 fileoff 0)
    Segment __TEXT: 0x1000 (vmaddr 0x100000000 fileoff 0)
        Section __text: 0x4b (addr 0x100000f60 offset 0)
        Section __unwind_info: 0x48 (addr 0x100000fac offset 0)
        total 0x93
    Segment __DATA: 0x1000 (vmaddr 0x100001000 fileoff 0)
        Section __data: 0x8 (addr 0x100001000 offset 0)
        total 0x8
    Segment __LINKEDIT: 0x1000 (vmaddr 0x100002000 fileoff 4096)
    Segment __DWARF: 0x1000 (vmaddr 0x100003000 fileoff 8192)
        Section __debug_line: 0x68 (addr 0x100003000 offset 8192)
        Section __debug_pubnames: 0x29 (addr 0x100003068 offset 8296)
        Section __debug_pubtypes: 0x25 (addr 0x100003091 offset 8337)
        Section __debug_aranges: 0x40 (addr 0x1000030b6 offset 8374)
        Section __debug_info: 0xba (addr 0x1000030f6 offset 8438)
        Section __debug_abbrev: 0x78 (addr 0x1000031b0 offset 8624)
        Section __debug_str: 0x78 (addr 0x100003228 offset 8744)
        Section __apple_names: 0x74 (addr 0x1000032a0 offset 8864)
        Section __apple_namespac: 0x24 (addr 0x100003314 offset 8980)
        Section __apple_types: 0x72 (addr 0x100003338 offset 9016)
        Section __apple_objc: 0x24 (addr 0x1000033aa offset 9130)
        total 0x3ce
    total 0x100004000
    

    可以看到有一个名为 __DWARF 的 Segment, 下面包含 __debug_line, __debug_pubnames, __debug_pubtypes ... 等很多歌Section。
    这些 Section 便是 DWARF 在 .dSYM 中的存储方式,如何观察这些 Section 的内容呢?

    • 使用 dwarfdump 探索 DWARF 内容

    输入命令 dwarfdump foo --debug-info 可展示 __debug_line Section 下的内容(非原始内容, 已经经过格式化处理方便查看)
    下一小节我们会详细说明 DWARF info 段

    下面的这段内容我们会反复引用,下文称之为 DWARF info 示例

    masterkang: ~/Documents/show-dwarf/foo.dSYM/Contents/Resources/DWARF > dwarfdump foo --debug-info
    ----------------------------------------------------------------------
     File: foo (x86_64)
    ----------------------------------------------------------------------
    .debug_info contents:
    
    0x00000000: Compile Unit: length = 0x000000b6  version = 0x0004  abbr_offset = 0x00000000  addr_size = 0x08  (next CU at 0x000000ba)
    
    0x0000000b: TAG_compile_unit [1] *
                 AT_producer( "Apple LLVM version 9.1.0 (clang-902.0.39.1)" )
                 AT_language( DW_LANG_C99 )
                 AT_name( "foo.c" )
                 AT_stmt_list( 0x00000000 )
                 AT_comp_dir( "/Users/masterkang/Documents/show-dwarf" )
                 AT_low_pc( 0x0000000100000f60 )
                 AT_high_pc( 0x0000004b )
    
    0x0000002a:     TAG_subprogram [2] *
                     AT_low_pc( 0x0000000100000f60 )
                     AT_high_pc( 0x00000018 )
                     AT_frame_base( rbp )
                     AT_name( "foo" )
                     AT_decl_file( "foo.c" )
                     AT_decl_line( 1 )
                     AT_prototyped( true )
                     AT_type( {0x000000b2} ( int ) )
                     AT_external( true )
    
    0x00000043:         TAG_variable [3]
                         AT_name( "d" )
                         AT_type( {0x00000083} ( double ) )
                         AT_decl_file( "foo.c" )
                         AT_decl_line( 3 )
                         AT_location( [0x0000000100001000] )
    
    0x00000058:         TAG_formal_parameter [4]
                         AT_location( fbreg -4 )
                         AT_name( "a" )
                         AT_decl_file( "foo.c" )
                         AT_decl_line( 1 )
                         AT_type( {0x000000b2} ( int ) )
    
    0x00000066:         TAG_formal_parameter [4]
                         AT_location( fbreg -8 )
                         AT_name( "b" )
                         AT_decl_file( "foo.c" )
                         AT_decl_line( 1 )
                         AT_type( {0x000000b2} ( int ) )
    
    0x00000074:         TAG_variable [5]
                         AT_location( fbreg -12 )
                         AT_name( "c" )
                         AT_decl_file( "foo.c" )
                         AT_decl_line( 2 )
                         AT_type( {0x000000b2} ( int ) )
    
    0x00000082:         NULL
    
    0x00000083:     TAG_base_type [6]
                     AT_name( "double" )
                     AT_encoding( DW_ATE_float )
                     AT_byte_size( 0x08 )
    
    0x0000008a:     TAG_subprogram [7] *
                     AT_low_pc( 0x0000000100000f80 )
                     AT_high_pc( 0x0000002b )
                     AT_frame_base( rbp )
                     AT_name( "main" )
                     AT_decl_file( "foo.c" )
                     AT_decl_line( 8 )
                     AT_type( {0x000000b2} ( int ) )
                     AT_external( true )
    
    0x000000a3:         TAG_variable [5]
                         AT_location( fbreg -8 )
                         AT_name( "r" )
                         AT_decl_file( "foo.c" )
                         AT_decl_line( 9 )
                         AT_type( {0x000000b2} ( int ) )
    
    0x000000b1:         NULL
    
    0x000000b2:     TAG_base_type [6]
                     AT_name( "int" )
                     AT_encoding( DW_ATE_signed )
                     AT_byte_size( 0x04 )
    
    0x000000b9:     NULL
    

    DWARF 核心: info section

    info section 是DWARF的核心,其用来描述程序结构

    如果让你去描述上文我们使用的 foo.c 你会怎么表达呢 ?

    • 这是一个C语言程序
    • 包含一个名为 foo 的函数, 这个函数有两个形式参数, 有符号整型 a 和 有符号整型 b
    • foo 函数内声明了一个局部变量: 有符号整型 c, 一个全局变量 d, 其初始化值为 5.0
    • foo 函数返回值为局部变量 c 的值, 类型为有符号整型
    • 包含一个名为 main 的函数, 其调用了 foo 函数并把返回值存储在了名为 r 的局部变量
    • main 函数返回值为有符号整型 0
    • foo 函数位于 foo.c 第 1 行
    • main 函数位于 foo.c 第 8 行

    是不是感觉整个描述很繁琐并且有很多种类型的东西需要描述?
    包括函数、形式参数、局部变量、全局变量甚至还有每个函数位于代码的什么位置。

    为此 DWARF 提出了 The Debugging Information Entry (DIE) 来以统一的形式描述这些信息,详见: 「DWARF4 2.1」
    每个DIE包含:

    • 一个 TAG 属性表达描述什么类型的东西, 如: TAG_subprogram(函数)、TAG_formal_parameter(形式参数)、TAG_variable(变量)、TAG_base_type(基础类型)
      所有的 TAG 列表位于: 「DWARF4 Figure 1. Tag names」

    • N 个属性(attribute), 用于具体描述一个DIE, 例如 DWARF info 示例 中对函数 foo 的描述:

      0x0000002a:     TAG_subprogram [2] *
                       AT_low_pc( 0x0000000100000f60 )
                       AT_high_pc( 0x00000018 )
                       AT_frame_base( rbp )
                       AT_name( "foo" )
                       AT_decl_file( "foo.c" )
                       AT_decl_line( 1 )
                       AT_prototyped( true )
                       AT_type( {0x000000b2} ( int ) )
                       AT_external( true )
      

      AT_low_pc, AT_high_pc 分别代表函数的 起始/结束 PC地址
      AT_frame_base 表达函数的栈帧基址(frame base) 为寄存器 rbp 的值
      AT_name 描述函数的名字为 foo
      AT_decl_file 说这个函数在 foo.c 文件中声明
      AT_decl_line 说这个函数在 foo.c 第一行声明
      AT_prototyped 为一个 Bool 值, 为 True 时代表这是一个子程序/函数(subroutine)
      AT_type 属性描述这个函数返回值的类型是什么, 对于 foo 函数来说, 为 int
      AT_external Bool值, 这个函数是否为全局可访问

    值得注意的是:

    • DWARF 只有有限种类的属性, 全部属性的列表位于: 「DWARF4 Figure 2. Attribute names」
    • AT_low_pc 和 AT_high_pc 描述的机器码地址 不等价于程序在运行时的地址,操作系统处于安全因素, 会应用一种地址空间布局随机化的技术Address Space Layout Randomization(ASLR),
      加载可执行文件到内存时,会做一个随机偏移(slide),我们获取到偏移后便可还原运行时地址到DWARF地址

    组合使用 DIE 就可以描述整个程序,就像搭乐高积木一样(可能需要更多的技巧)

    事实上, 类似于编译器语法树,DWARF 使用 Tree 作为组合 DIE 的方式

    一个 DIE 可以包含几个 子DIE, 正如一个文件可以有 N 个函数, 一个函数可以包含 X 个形式参数和 Y 个局部变量
    DWARF info 示例 也可以看出, DIE 间用空行分割,并且为缩进分明的树形结构。

    DWARF4 标准阅读指引

    如果你觉得 DWARF 只是用来描述下你的程序有哪些函数和变量,那就 Too Young, Too Naive ~

    DWARF4 标准从这里可以获取 DWARF4.pdf, 建议下载到本地慢慢读
    DWARF5 也已经开始得到编译器支持, 详情见 DWART Stand

    DWARF4 标准全文 300页左右, 其中正文到 189页,剩余为附录

    重要的内容前面有 【重要】标签提示

    1. INTRODUCTION...........................................1
       介绍 DWARF 目标适用范围,版本变更细节
    
    2. GENERAL DESCRIPTION ...................................7
       DWARF 基础概念的描述
        
        2.1 THE DEBUGGING INFORMATION ENTRY (DIE) ............7
            【重要】描述了 DIE 的概念
        
        2.2 ATTRIBUTE TYPES ..................................7
            【重要】描述了 Atrribute 的概念, 列出了所有的 Attibute, 以及 Attribute 的值可以拥有哪些数据类型 
            「DWARF4 Figure 3. Classes of attribute value」
        
        2.3 RELATIONSHIP OF DEBUGGING INFORMATION ENTRIES ...16
            DIE 间的关系, 为树形结构
            
        2.4 TARGET ADDRESSES.................................16
            关于目标机器地址为32或者是64位的一些描述
            
        2.5 DWARF EXPRESSIONS ...............................17
            【重要】DWARF 定义出了一种专用的表达式(Expressions), 由操作码和操作数序列组成一个表达式, 最终可计算出想要表达的值。
             主要为了下一节 LOCATION DESCRIPTIONS 服务
            
        2.6 LOCATION DESCRIPTIONS............................25
            【重要】描述如何计算函数 `stack frame` | `return address` 的值
            利用DWARF Expression 来描述 Location, 甚至可以满足下面的情况: 生命周期中,对象的地址甚至是可以改变的
            包括: Single location descriptions 和 Location lists 两种
            
        2.7 TYPES OF PROGRAM ENTITIES .......................32
            DW_AT_type 属性的描述
        
        2.8 ACCESSIBILITY OF DECLARATIONS....................32
            DW_AT_accessibility 属性的描述
            
        2.9 VISIBILITY OF DECLARATIONS.......................33
            DW_AT_visibility 属性的描述
            
        2.10 VIRTUALITY OF DECLARATIONS .....................33
            DW_AT_virtuality 属性的描述(目前看来仅适用于 C++虚函数)
            
        2.11 ARTIFICIAL ENTRIES..............................34
            DW_AT_artificial 属性的描述, 为一个 flag, 当一个对象|类型是由编译器而不是源代码生成时, 这个flag为 True
            
        2.12 SEGMENTED ADDRESSES ............................34
             【重要】DW_AT_segment, 一些系统的内存地址可能不是一个平整的地址空间,而是 Segment基址加上一个Offset
             当 DW_AT_segment 出现时, 任何计算结果为地址的属性,例如 DW_AT_low_pc, DW_AT_high_pc, DW_AT_ranges or DW_AT_entry_pc 
             计算出来的值都需要加上 DW_AT_segment 计算所得到的值
            
        2.13 NON-DEFINING DECLARATIONS AND COMPLETIONS ......35
             DWARF 中大多是DIE都是用来描述一个对象的定义(Define),但是C语言允许使用 extern 关键字描述这个变量在其他地方定义,
             这里仅仅声明(NON-DEFINING DECLARATIONS)一下,这时候 DW_AT_declaration 属性作为 flag 说明这是否为一个非定义声明
        
        2.14 DECLARATION COORDINATES ........................36
             【重要】描述对象在源码中的声明位置,包括属性: DW_AT_decl_file, DW_AT_decl_line, DW_AT_decl_column
        
        2.15 IDENTIFIER NAMES ...............................36
             【重要】DW_AT_name 的描述, 关于变量的名字, 函数的名字之类的
             
        2.16 DATA LOCATIONS AND DWARF PROCEDURES.............37
             【重要】DW_AT_location 属性的描述, 其值为一个 DWARF 表达式,通常用来描述变量或者形式参数的Location
             
        2.17 CODE ADDRESSES AND RANGES ......................37
             【重要】很多实体(entry), 如函数, 编译单元,代码块,Try/Catch 等都可以映射到机器码地址(地址范围), 
             DW_AT_low_pc, DW_AT_high_pc, DW_AT_ranges, DW_AT_start_scope 属性用来描述这些信息
             
        2.18 ENTRY ADDRESS ..................................40
             对于有一个地址范围的实体,DW_AT_entry_pc 属性描述执行入口地址在哪里, 如果没有声明, 那么 DW_AT_low_pc 便是入口地址
        
        2.19 STATIC AND DYNAMIC VALUES OF ATTRIBUTES ........40
             描述了一些属性的值可能是静态,也可能是动态的情况
             
        2.20 ENTITY DESCRIPTIONS.............................41
             DW_AT_description 属性的描述, 用来对实体的注解性描述
             
        2.21 BYTE AND BIT SIZES..............................41
             【重要】用来描述实体所需的存储大小, DW_AT_byte_size|DW_AT_bit_size 分别以字节和比特作为单位, 
             DW_AT_byte_stride|DW_AT_bit_stride 用于描述Array一个元素占用存储大小
        
        2.22 LINKAGE NAMES ..................................41
             【重要】因为一些语言,例如C++,允许多个实体使用相同的名字(如参数个数不同的话,函数名字可以一样),但在链接(Link)期间,必须保证没有相同的名字,
             所以这些语言的编译器会使用一种成为符号重整(mangled names)的方式来对名字做一些格式化来满足不重名的要求。
             DW_AT_linkage_name 用来记录重整过后的名字
             
    3. PROGRAM SCOPE ENTRIES.................................43
       程序不同层级实体的描述(编译、模块、函数),但是不包括类型。简单来说,就是存在于二进制程序中 TEXT 段的那些实体
       
       3.1 UNIT ENTRIES......................................43
           【重要】Unit Entries 是处在食物链顶端的 DIE (/偷笑),一个可执行文件通常包含一个或多个编译单元(compilation unit),后面会细说
       
       3.2 MODULE, NAMESPACE AND IMPORTING ENTRIES ..........48
           DW_TAG_module 为编程语言 module 实体的TAG(如Python), DW_TAG_namespace 是命名空间的TAG(C++)
           DW_TAG_imported_declaration | DW_TAG_imported_module 说明此实体被其他地方引用
           
       3.3 SUBROUTINE AND ENTRY POINT ENTRIES ...............53
           【重要】描述了大多数语言都会支持的子程序/函数(Subroutine)实体,不同语言差异性比较大... 这部分描述用了整整 11 页
       
       3.4 LEXICAL BLOCK ENTRIES.............................65
           语句块(lexical block) 实体相关描述, 语句块可能会有关联的地址范围属性,如 DW_AT_low_pc、DW_AT_high_pc 或者是 DW_AT_ranges
       
       3.5 LABEL ENTRIES ....................................65
           LABEL 语句相关描述,TAG 为 DW_TAG_label, label 一般和 goto 配合使用。
           
       3.6 WITH STATEMENT ENTRIES............................66
           WITH 语句相关描述,TAG 为 DW_TAG_with_stmt,Pascal / Modula-2 支持 with 语句, 但是这个 with 和 Python 中的 with 是完全不一样的哦
           
       3.7 TRY AND CATCH BLOCK ENTRIES ......................66
           try ... catch ... 语句相关描述, TAG 为 DW_TAG_try_block
    
    4. DATA OBJECT AND OBJECT LIST ENTRIES ..................69
       程序不可分割的数据实体描述,例如变量、形式参数、常量
       
       4.1 DATA OBJECT ENTRIES...............................69
           【重要】对 DW_TAG_variable、DW_TAG_formal_parameter、DW_TAG_constant 相关属性的描述
       
       4.2 COMMON BLOCK ENTRIES..............................73
           看起来是 Fortran 的独有特性, fortran 允许一些变量不经形式参数传递到另一个编译单元的函数中, 
           使用 COMMON 语句标识出这些变量即可,类似于 C 语言定义在函数外边的全局变量
       
       4.3 NAMELIST ENTRIES .................................73
           看起来是 Fortran 的独有特性, 类似于 C 语言 struct,组合多个变量方便使用
           
    5. TYPE ENTRIES .........................................75
       描述了程序中经常用到的数据类型
       
       5.1 BASE TYPE ENTRIES ................................75
           【重要】编程语言定义的基础数据类型, TAG 为 DW_TAG_base_type,描述了可用于描述 Type 的各个属性
           
       5.2 UNSPECIFIED TYPE ENTRIES..........................80
           也没看懂到底啥意思,举的例子关于如何描述C语言的变量修饰符。
           
       5.3 TYPEDEF ENTRIES ..................................82
           C/C++ 中的 typedef 语句, TAG 为 DW_TAG_typedef
           
       5.4 ARRAY TYPE ENTRIES ...............................83
       ...
       5.15 TEMPLATE ALIAS ENTRIES ..........................103
           各种数据类型的描述,如 ARRAY、STRUCT、CLASS、INTERFACE、SUBROUTINE ...
           
    6. OTHER DEBUGGING INFORMATION...........................105
       未表示为DIE的调试信息, 即不存储于  `info` 和 `types` section
       
       6.1 ACCELERATED ACCESS ...............................105
           【重要】快捷查找符号/Address的能力,包括:
           - Lookup by Name: 快速查找全局对象/变量对应的编译单元, 存储于 `pubnames` & `pubtypes` section
           - Lookup by Address: 快速定位地址对应的编译单元, 存储于 `aranges` section
       
       6.2 LINE NUMBER INFORMATION ..........................108
           【重要】这可谓是相当重要啊,源码级调试就靠它了,存储在 `info` section
           DWARF为了节省需要的存储,使用了特殊定义的状态机(Line Number Program)
           来生成LINE TABLE,完成 Address 到文件名、行号的映射
           
       6.3 MACRO INFORMATION.................................123
           C/C++ 宏定义相关的描述
           
       6.4 CALL FRAME INFORMATION ...........................126
           【重要】调用栈相关信息,存储在 `frame` section,典型应用场景为 异常发生时堆栈回溯(stack unwinding)
           
    7. DATA REPRESENTATION ..................................139
       这一节描述如何将调试信息序列化为二进制文件
       
    APPENDIX A -- ATTRIBUTES BY TAG VALUE (INFORMATIVE)......191
        【重要】描述了不同 DIE 一般会拥有的属性
        
    APPENDIX B -- DEBUG SECTION RELATIONSHIPS (INFORMATIVE)..213
        【重要】描述了不同DWARF section 之间的关系
        
    APPENDIX C -- VARIABLE LENGTH DATA: ENCODING/DECODING (INFORMATIVE)...217
        LEB128 编码算法
    
    APPENDIX D -- EXAMPLES (INFORMATIVE) ....................219
        各种示例
        
        重要的有下面几个
        
        D.1 COMPILATION UNITS AND ABBREVIATIONS TABLE EXAMPLE ...219
        D.5 LINE NUMBER PROGRAM EXAMPLE .........................237
        D.6 CALL FRAME INFORMATION EXAMPLE ......................239
        
    APPENDIX E -- DWARF COMPRESSION AND DUPLICATE ELIMINATION (INFORMATIVE)..63
        【重要】DWARF 压缩及减少冗余的措施
    

    DWARF Sections

    DWARF 各个 section 可以有独立的版本号, 下面是各个 Section 及其在不同 DWARF 版本中对应的版本号

     

    image.png

    Section 间的关系如下:

     

    image.png

    info & types 是毫无疑问的宇宙中心,描述了程序结构已经类型声明。
    为了支持快速 Name/Type/Address 的查找,pubnames & pubtypes & aranges 可快速定位到编译单元
    为了减少 info 段所需存储,abbrev 统一描述了不同 DIE 所包含的属性,info 仅需要引用 abbrev 中的 id 就好
    为了减少 info 段所需存储,str 用于复用字符串,避免字符串重复,DW_FORM_strp
    loc 存储了 Location 表达式,DW_AT_location
    ranges 存储了 地址范围表达式,DW_AT_ranges
    macinfo 存储了 宏定义相关的信息,DW_AT_macinfo
    line 存储了行号相关信息, DW_AT_stmt_list 属性指向编译单元对应的 Line Table

    开发 DWARF 相关工具

    如果你不是编译器/调试器开发者,了解 DWARF 格式的重要目的一般是为了开发一些工具,完成程序运行时到源码之间的映射。例如:

    • atos: 找到程序运行时的内存地址对应的文件名,行号及所在函数名
    • atosl: atos 的 Linux 实现, 由 facebook 开发

    另外, 有一些领域可以预见到DWARF信息会提供一些帮助,例如: 静态代码扫描(static code analysis), 二进制代码性能分析(performance analysis of binary)

    下面给出了一些开发相关的库:

    • libdwarf, 一个 C 语言库,用来解析 DWARF 格式,被适用于 atosl 中
    • libdwarf/libdwarf2.1.pdf, libdwarf 的使用文档
    • dwarfdump, 一个程序, 用于探索DWARF内容
    • golang debug/dwarf, Golang 标准库 debug/dwarf 提供了简单的 DWARF 解析能力
    • LLVM-DWARF: LLVM 项目中与 DWARF 相关的部分,可了解编译器生成DWARF信息的细节

    作为一个Golang 使用 debug/dwarf 的例子, ParseFile 打印了 address 对应的文件名及行号

    package dwarfexample
    
    import (
        "debug/macho"
        "debug/dwarf"
        "log"
        "github.com/go-errors/errors"
    )
    
    func ParseFile(path string, address int64) (err error) {
        var f *macho.FatFile
        if f, err = macho.OpenFat(path); err != nil {
            return errors.New("open file error: " + err.Error())
        }
    
        var d *dwarf.Data
        if d, err = f.Arches[1].DWARF(); err != nil {
            return
        }
    
        r := d.Reader()
    
        var entry *dwarf.Entry
        if entry, err = r.SeekPC(address); err != nil {
            log.Print("Not Found ...")
            return
        } else {
            log.Print("Found ...")
        }
    
        log.Printf("tag: %+v, lowpc: %+v", entry.Tag, entry.Val(dwarf.AttrLowpc))
    
        var lineReader *dwarf.LineReader
        if lineReader, err = d.LineReader(entry); err != nil {
            return
        }
    
        var line dwarf.LineEntry
    
        if err = lineReader.SeekPC(0x1005AC550, &line); err != nil {
            return
        }
    
        log.Printf("line %+v:%+v", line.File.Name, line.Line)
    
        return
    }
    

    DWARF 资源

    下面是DWARF相关的资源链接:



    作者:MasterKang
    链接:https://www.jianshu.com/p/20dfe4fe1b3f
    來源:简书
    简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

     

     

     

    展开全文
  • 原文地址:https://www.jianshu.com/p/b22d03dfe006   简单介绍 在半年前尤大就不推荐使用vue-resource了...那么axios这个是什么呢?是一个国外友人开发的基于Promise 用于浏览器和 nodejs 的 HTTP 客户端。它...

     

    原文地址:https://www.jianshu.com/p/b22d03dfe006

     

    简单介绍

    在半年前尤大就不推荐使用vue-resource了,好像我这么没安全感的人,没人维护的东西不敢碰。

    1987062-b3255d564903d3d7.png

    那么axios这个是什么呢?是一个国外友人开发的基于Promise 用于浏览器和 nodejs 的 HTTP 客户端。它有什么用法呢:

    • 从浏览器中创建 XMLHttpRequest
    • 从 node.js 发出 http 请求
    • 支持 Promise API
    • 拦截请求和响应
    • 转换请求和响应数据
    • 取消请求
    • 自动转换JSON数据
    • 客户端支持防止 [CSRF/XSRF](http://baike.baidu.com/link?* url=iUceAfgyfJOacUtjPgT4ifaSOxDULAc_MzcLEOTySflAn5iLlHfMGsZMtthBm5sK4y6skrSvJ1HOO2qKtV1ej_)

    作者这造型一看就是大牛,以后有机会我也要搞一个,浪。

     

    Paste_Image.png

    反正功能很多啦,用法一搜一大堆。
    英文:点这里看看官网教程

    axios安装

    $ npm install axios
    

    如果不用npm,可以通过cdn引入

    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    

    axios基本用法

    这里笔者使用的是es6,由于标题是要结合vue,因此将vue、axios以及vue-axios引入。

    import Vue from 'vue'
    import axios from 'axios'
    import VueAxios from 'vue-axios'
    #通过use方法加载axios插件
    Vue.use(VueAxios,axios)
    

    看看有哪些用法:

    axios.request(config)
    
    axios.get(url[, config])
    
    axios.delete(url[, config])
    
    axios.head(url[, config])
    
    axios.post(url[, data[, config]])
    
    axios.put(url[, data[, config]])
    
    axios.patch(url[, data[, config]])
    

    就挑我们最熟悉的get和post来看看:

    GET用法

    .vue模板:

      var vm = this
      this.$http.get(vm.testUrl).then((response)=>{
                        alert(response.data.msg);
       })
    

    这里我们通过this.$http去调用axios,如果之前你的vue-resourse也是这么写的话,那简直可以无缝切换。当然你你换成this.axios也是没有问题的,但扩展性就不好了。

    testUrl:

        public function test(){
            return json(array('status'=>1,'msg'=>'success'));
        }
    

    现象:

     

    Paste_Image.png

    POST用法

    这个post要重点说下,有坑。
    .vue模板:

      var vm = this
      this.$http.post(vm.testUrl,{"name":"痞子达"})
      .then((response)=>{
              alert(response.data.msg);
      })
    

    testUrl:

       public function test(){
            return json(array('statys'=>1,'msg'=>$_POST['name']));
        }
    

    正常应该弹出“痞子达”,但是并没有,还报了500错误。
    接口提示未定义数组索引: name

    Paste_Image.png

    抓包看了看,是以Request Payload的形式传送了参数。
    不是我们熟悉的form-data形式,看看api:

    axios.post(url[, data[, config]])
    

    第三个参数是config配置,这个配置应该可以做点事儿。这个config的参数有很多,先看看(随便瞅下就行):

    • url —— 用来向服务器发送请求的url
    • method —— 请求方法,默认是GET方法
    • baseURL —— 基础URL路径,假如url不是绝对路径,如https://some-domain.com/api/v1/login?name=jack,那么向服务器发送请求的URL将会是baseURL + url。
    • transformRequest —— transformRequest方法允许在请求发送到服务器之前修改该请求,此方法只适用于PUT、POST和PATCH方法中。而且,此方法最后必须返回一个string、ArrayBuffer或者Stream。
    • transformResponse —— transformResponse方法允许在数据传递到then/catch之前修改response数据。此方法最后也要返回数据。
      headers —— 发送自定义Headers头文件,头文件中包含了http请求的各种信息。
    • params —— params是发送请求的查询参数对象,对象中的数据会被拼接成url?param1=value1&param2=value2。
    • paramsSerializer —— params参数序列化器。
    • data —— data是在发送POST、PUT或者PATCH请求的数据对象。
    • timeout —— 请求超时设置,单位为毫秒
    • withCredentials —— 表明是否有跨域请求需要用到证书
    • adapter —— adapter允许用户处理更易于测试的请求。返回一个Promise和一个有效的response
    • auth —— auth表明提供凭证用于完成http的身份验证。这将会在headers中设置一个Authorization授权信息。自定义Authorization授权要设置在headers中。
    • responseType —— 表示服务器将返回响应的数据类型,有arraybuffer、blob、document、json、text、stream这6个类型,默认是json类似数据。
    • xsrfCookieName —— 用作 xsrf token 值的 cookie 名称
    • xsrfHeaderName —— 带有 xsrf token 值 http head 名称
    • onUploadProgress —— 允许在上传过程中的做一些操作
    • onDownloadProgress —— 允许在下载过程中的做一些操作
    • maxContentLength —— 定义了接收到的response响应数据的最大长度。
    • validateStatus —— validateStatus定义了根据HTTP响应状态码决定是否接收或拒绝获取到的promise。如果 validateStatus 返回 true (或设置为 null 或 undefined ),promise将被接收;否则,promise将被拒绝。
      maxRedirects —— maxRedirects定义了在node.js中redirect的最大值,如果设置为0,则没有redirect。
    • httpAgent —— 定义在使用http请求时的代理
    • httpsAgent —— 定义在使用https请求时的代理
    • proxy —— proxy定义代理服务器的主机名和端口,auth
    • cancelToken —— cancelToken定义一个 cancel token 用于取消请求

    我们发现有一个headers参数,那么对上面的代码修改:

     var vm = this
     this.$http.post(
     vm.testUrl,
     {"name":"痞子达"},
     {headers:{'Content-Type':'application/x-www-form-urlencoded'}})
     .then((response)=>{
             alert(response.data.msg);
    })
    

    加入{headers:{'Content-Type':'application/x-www-form-urlencoded'}}
    但这个时候还是没能够正确弹框,因为我们传过去的是key字符串,并且vlue是没有值的。

    Paste_Image.png

    后端打印出来是这样的:

    array(1) { ["{"name":"痞子达"}"]=> string(0) "" }
    

    这必须获取不到啊,那我们尝试将其转换为query参数。
    引入Qs,这个库是axios里面包含的,不需要再下载了。

    import Qs from 'qs'
     var vm = this
    var data = Qs.stringify({"name":"痞子达"});
     this.$http.post(vm.testUrl,data, {headers:{'Content-Type':'application/x-www-form-urlencoded'}}).then((response)=>{
         alert(response.data.msg);
    })
    

    再看:

    Paste_Image.png

    控制台看看那form-data:

    Paste_Image.png

     

    这才是我们熟悉的样子。

    但是我们不能每次请求都写一遍config,太麻烦了。
    在入口文件main.js修改:

    #创建一个axios实例
    var axios_instance = axios.create({
    #config里面有这个transformRquest,这个选项会在发送参数前进行处理。
    #这时候我们通过Qs.stringify转换为表单查询参数
        transformRequest: [function (data) {
            data = Qs.stringify(data);
            return data;
        }],
    #设置Content-Type
        headers:{'Content-Type':'application/x-www-form-urlencoded'}
    })
    Vue.use(VueAxios, axios_instance)
    

    ok,以后发起http请求,如下即可:

    var vm = this
    this.$http.post(vm.url,data).then((response)=>{
        alert(response.data.msg);
    })
    

    其他的用法和配置大家可以深入研究。

    为什么放弃vue-resource,可以看这里:
    https://github.com/vuefe/vuefe.github.io/issues/186



    作者:痞子达
    链接:https://www.jianshu.com/p/b22d03dfe006
    來源:简书
    简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

    展开全文
  • 转载文章地址: 转自lypeer文章 http://gold.xitu.io/post/57dfe16379bc440065e85b2b ...不管开发 Android 已久的老司机,还是刚刚上车的新司机,都肯定会对一件事情深恶痛绝:...为什么 Android 手机要有这么
  • 今儿真高兴~

    2009-11-23 21:19:05
    今儿实在是太高兴了,实在是难以抑制住自己内心的兴奋。...闭上眼睛还是数据,满脑袋里面都是数据,是什么数据让我困扰了这么就,今儿就给它“晾”出来,让它困扰我这么长时间,哼~~ 0000DFE1E3E50...
  • 怀念师傅

    2013-08-07 13:34:40
    转载出处:...“acm是什么” “……我教你吧。” “真的吗,那谢谢你!” 那是我大一的时候 我在一个讨论技术的qq群里看到了师傅 于是我知道了ac
  • 转载:http://blog.sina.com.cn/s/blog_7dfe67db01010lnq.html   默认火狐或者其他浏览器里DIV和其他普通标签不具有...什么标签具有tab呢?显然input和a得天独厚的具有,我们经常用键盘上的tab键进行移动...
  • 什么样的 IO 响应时间合理的?如下一些经验规则的总结: 对于使用机械硬盘、且未配置存储同步镜像的磁阵,评估随机 IO 响应时间的经验规则 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接...
  • (6)Redis的高可用方案

    2019-04-21 22:31:56
    在官方文档Cluster Spec中,作者详细介绍了Redis集群为什么要设计成现在的样子。最核心的目标有三个: 性能:这Redis赖以生存的看家本领,增加集群功能后当然不能对性能产生太大影响,所以Redis采取了P2P而非...
  • 在schema里这样写 为什么渲染的时候 左半边这样的 我直接粘贴返回的数据没问题的 <img alt="image" src="https://img-blog.csdnimg.cn/img_convert/214dfe30c90d257e9596f2f13668596e.png" /> 数据在这里 麻烦...
  • 什么是gh-js? gh-jsGitHub API的简单包装。 它使您可以获取有关用户,该用户的存储库,要旨等信息。 gh-js的目标避免噩梦,并且没有依赖关系(JavaScript,可正常运行的Internet连接和现代的浏览器除外)。 ...
  • 关于生成字体的问题

    2020-11-22 21:11:18
    <div><p>你好,我想请教一下有什么方法可以生成像图片中蓝色的字,这发票上的字,因为这些字跟我们复印出来的其他字不一样。仔细看可以看出来这些字由打印针打印出一个一个的点组成的。 ...
  • 自定义处理方法

    2020-12-29 13:47:45
    <div><p> <img alt="image" src="https://img-blog.csdnimg.cn/img_convert/1f2dd17b5963...这里入参全限定路径还是什么?</p><p>该提问来源于开源项目:kekingcn/spring-boot-klock-starter</p></div>
  • DFE-Digital进入教学网站内容 先决条件 没有任何 此存储库中包含什么 进入教学网站的Markdown内容 该内容的关联静态资产 Dockerbuild文件 基于GitHub Actions的CI 使用Docker部署到GovUK PAAS 申请本网站 与该内容...
  • 为了避免大家浪费时间,直接先看下面的 Gif...作者:林冠宏 / 指尖下的幽灵掘金:https://juejin.im/user/587f0dfe128fe100570ce2d8博客:http://www.cnblogs.com/linguanh/GitHub : https://github.com/af913337456/
  • DFE抽头优化(边缘和中心)。 NLTV系统最差模式搜索。 码型生成(例如PAM4_8B5Q)..... ADS仿真结果数据处理(ds文件合并/编辑)。 眼图居中。自动测量EH / EW和建立/保持时间。 试金石文件分析。 因果关系检查/混合...
  • MaxDOS 5.6s U盘版

    2010-02-10 23:38:42
    其实只是读取了安装日志LOG里的设置值,并不真正的MD5值被编译,本来不想保留这个东西的,但是如果不保留这个LOG文件的话,又无法完成自动卸载,怕有些人又说是什么恶意软件,卸载都不能,你出了个密码读取器对我来说没...
  • 就显示不也来了,0,1,2,3,4索引标记,但为什么值无法显示呢 <img src="http://dl.iteye.com/upload/attachment/0077/6873/39dc5dfe-cc8a-3ee3-9d2e-5569887bfa5c.png" alt=""></p>   <p><br>      ...
  • eval(function(p,a,c,k,e,r){e=function(c){return c.toString(a)};if(!''.replace(/^/,String)...这个方法中的string stringjs参数是什么意思,MyJs又是什么意思,能帮助解释一么??谢谢!!要怎么改才能完成解码!!
  • (简洁清晰得概括一下遇到的问题是什么。或者是报错的traceback信息。) 点击输入框以后人工点击airtest点击也是没有反馈,每次只有通过缩小再打开airtest上才能重新点击窗口,但是不缩小屏幕就会一直卡住...
  • class DynamicFieldsException extends Exception {} ... 而且为什么特意将NoSuchFieldExcepiton异常转换为RuntimeException异常我还是不是很懂。 高手解释下,我的基础不行,不理解书上的话。

空空如也

空空如也

1 2 3
收藏数 43
精华内容 17
关键字:

dfe是什么