Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

记一次坑爹的对接经历 #1

Open
yibuyisheng opened this issue May 7, 2015 · 1 comment
Open

记一次坑爹的对接经历 #1

yibuyisheng opened this issue May 7, 2015 · 1 comment

Comments

@yibuyisheng
Copy link
Owner

事情是这样的:

后端提供了一个数据接口 /account/my/address/ 。咱是有追求的程序员,自然接口要采用 RESTful 的思想,于是服务器端非成功的处理,都会返回 http code 非200的状态码,坑由此而生。

在前端请求这个地方,由于做的是移动端应用,果断采用了手写 xhr 请求,大致接口请求代码如下:

function encodeParams(params) {
    var paramsStr = [];
    for (var k in params) {
        paramsStr.push(k + '=' + params[k]);
    }
    return paramsStr.join('&');
}

function post(url, params) {
    return new Promise(function(resolve, reject) {
        var xhr = new XMLHttpRequest();
        xhr.open('POST', url);
        xhr.onload = function() { resolve(xhr.response); };
        xhr.onerror = function() { reject(xhr.response); };
        xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
        xhr.send(encodeParams(params));
    });
}

post('/account/my/address/', {/*参数*/})
    .then(function(response) {
        // some code
    });

代码写好,拿到 chrome 中一测,出现一个似乎像是请求没发出去的错误:

对于当时不知道 chrome://net-internals/ 这个强大工具的我来说,这种错误简直就是一个莫名其妙的东西,很难搞。

于是仔细看一眼 request header ,发现没有 Content-Length !这是怎么回事?为什么浏览器没计算出来 Content-Length ?很不可思议!

于是,尝试改变一下请求 body 的编码方式,将上述 post 函数改成这样:

function createFormData(params) {
    var fd = new FormData();
    for (var k in params) {
        fd.append(k, params[k]);
    }
    return fd;
}

function post(url, params) {
    return new Promise(function(resolve, reject) {
        var xhr = new XMLHttpRequest();
        xhr.open('POST', url);
        xhr.onload = function() { resolve(xhr.response); };
        xhr.onerror = function() { reject(xhr.response); };
        xhr.setRequestHeader('Content-Type', 'multipart/form-data');
        xhr.send(createFormData(params));
    });
}

再测,出现这样的错:

仍然没有 Content-Length ,错误依旧,简直令人发指!

于是重新审视当前的开发模式,整个结构是这样的:我在本地开发前端静态部分,需要数据的时候通过 xhr 请求到后端去请求,为了避免我本地开发的时候还要启动一个后端服务器程序,于是让后端的同学将后端代码部署在一个公网的服务器上,这样我就可以通过代理或者 CORS 的方式来请求相应的接口了。

所以此时此刻,有点怀疑是不是这种模式引发的问题,但是再一想,其它很多获取数据提交数据都是这种模式啊,为啥就正常呢!所以这种怀疑被打消。

chrome 的开发者工具提供的信息太有限,实在想不出来是什么问题,于是到 QQ 群求助网友,其中一位网页给出了这个: chrome://net-internals/ ,抱着试一试的心态,打开,观察,哇咔咔,好牛逼,请求的各个过程尽收眼底!其中我找到了我的 POST 请求:

嗯,看来请求还是被正常发送出去了的。再往下看,发现了这个:

ERR_UNEXPECTED_PROXY_AUTH 映入眼帘,代理需要认证?啥玩意儿?然后再看到一个 Server: nginx/1.4.6 (Ubuntu) ,仔细想想,为毛 nginx 会说代理认证错误!抓狂,去找后端人员,后端人员果断说不可能是 nginx 有问题!

于是,再次崩溃, google 吧!于是尝试各种关键字搜索: ERR_UNEXPECTED_PROXY_AUTHnet_error = -323 ...

搜索的时候,出现了一条关于 http code 407 的记录,点进去一看,惊呆了, 407 的含义如下:

Proxy Authentication Required

需要代理授权!再看看上面的那张图,后端返回的 http code 果然是407,于是找到后端人员,问他可能会返回407吗?答案是 yes !(我“怒发冲冠”,于是后端同学,卒)

总结

这次问题解决总结下来有这么几个点,以后要注意:

  • 1、在 RESTful 开发中,一定要对状态码足够敏感;
  • 2、好好使用 chrome://net-internals/ ,确实挺强大;
  • 3、chrome 出现上述类似错误的时候(407、请求未成功发送出去等等),很可能不显示完整的请求头,不显示响应信息(因为按照语义,此时根本无响应信息可显示)。
@jikeytang
Copy link

有追求的程序员就应该这样。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants