我决定用Java发布一些东西,但却陷入了这样一个看似微不足道的任务。然后我感到沮丧,并在PHP中重写整个事情,它完美无缺。我尝试比较Java和PHP结果的输出,以及我注意到Curl设置 Content-Type:multipart / form-data; 而Java(正确?)将其设置为 application / x-www-form-urlencoded; 但这会触发 500内部服务器错误。这到底是怎么回事?
Java调试:
2017/12/11 19:10:36:236 EET [DEBUG] wire - http-outgoing-0 >> "POST /auth/register HTTP/1.1[\r][\n]"
2017/12/11 19:10:36:243 EET [DEBUG] wire - http-outgoing-0 >> "Cookie: XSRF-TOKEN=eyJpdiI6InJJRjdORWdzUVcwQVZMR2l2WnNHUWc9PSIsInZhbHVlIjoiZVFSc0V5MCtURFE4dTZHZGlwVXdna0VGMGZtNzh0aEF4eXJcL0ZcL3d6QWM4NVdJejJaeEptUDFcL0ZDeXBEOGlDMTltbEQ4cFg0c1wvK3h4Nkp3VEhJTmFRPT0iLCJtYWMiOiIzNmRjZGNmZGNmYTFkYTQzODQ2NjFkZWY3ZWVlZGJmNzBiNDFhNTQwNDU3ODAzMTA4MGNhYWRiY2VhNDU2ZmU2In0%3D;laravel_session=eyJpdiI6ImF3cGg2TUFvWm54b3J4Nml5NnlBYlE9PSIsInZhbHVlIjoiXC85ZzdJS2drRWxlWGExXC93bHFVNXRtTmFtTmcyblJ4cXY4eUhCY2toaWJGaFBcL2NjQllKekVrUWFvblhydWtSeHpySm4yWGlWbHE3Y3dXZjFxd3lXV3c9PSIsIm1hYyI6IjRlNGZiMjU4NDRmMWVjZjc1YzExYWM4ZjJlMTUyNzI0ZTY3NTAwYTUyZTdlNTdiZmQ2ZDg1NTk1OGE4OGQ3ZGMifQ%3D%3D[\r][\n]"
2017/12/11 19:10:36:243 EET [DEBUG] wire - http-outgoing-0 >> "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:57.0) Gecko/20100101 Firefox/57.0[\r][\n]"
2017/12/11 19:10:36:243 EET [DEBUG] wire - http-outgoing-0 >> "Accept: */*[\r][\n]"
2017/12/11 19:10:36:243 EET [DEBUG] wire - http-outgoing-0 >> "Content-Length: 146[\r][\n]"
2017/12/11 19:10:36:243 EET [DEBUG] wire - http-outgoing-0 >> "Content-Type: application/x-www-form-urlencoded; charset=UTF-8[\r][\n]"
2017/12/11 19:10:36:243 EET [DEBUG] wire - http-outgoing-0 >> "Host: xxx[\r][\n]"
2017/12/11 19:10:36:243 EET [DEBUG] wire - http-outgoing-0 >> "Connection: Keep-Alive[\r][\n]"
2017/12/11 19:10:36:243 EET [DEBUG] wire - http-outgoing-0 >> "Accept-Encoding: gzip,deflate[\r][\n]"
2017/12/11 19:10:36:243 EET [DEBUG] wire - http-outgoing-0 >> "[\r][\n]"
2017/12/11 19:10:36:244 EET [DEBUG] wire - http-outgoing-0 >> "username=jnfjkwejf&_token=ZTE8t5XDf2vmBcAWpSenELkEtqvhIp9FBSy0E1Ez&domain=xxx&password=qweqweqwe&password_confirmation=qweqweqwe&captcha=U8Aq3"
2017/12/11 19:10:36:319 EET [DEBUG] wire - http-outgoing-0 << "HTTP/1.1 500 Internal Server Error[\r][\n]"
Java代码:
HttpHost target = new HttpHost("xxx", 443, "https");
SSLContext sslcontext = SSLContexts.createSystemDefault();
SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(
sslcontext, new String[] { "TLSv1.2", "SSLv3" }, null,
SSLConnectionSocketFactory.getDefaultHostnameVerifier());
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", PlainConnectionSocketFactory.INSTANCE)
.register("https", sslConnectionSocketFactory)
.build();
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
CloseableHttpClient httpsclient = HttpClients.custom()
.setSSLSocketFactory(sslConnectionSocketFactory)
.setConnectionManager(cm)
.build();
ArrayList<NameValuePair> formparams = new ArrayList<>();
formparams.add(new BasicNameValuePair("username", "jnfjkwejf"));
formparams.add(new BasicNameValuePair("_token", _token));
formparams.add(new BasicNameValuePair("domain", "xxx"));
formparams.add(new BasicNameValuePair("password", "qweqweqwe"));
formparams.add(new BasicNameValuePair("password_confirmation", "qweqweqwe"));
formparams.add(new BasicNameValuePair("captcha", captcha));
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formparams, Consts.UTF_8);
HttpPost httppost = new HttpPost("/auth/register");
String fullCookie =
captchaConn.getHeaderFields().get("Set-Cookie").get(1).split(";")[0] + ";" +
captchaConn.getHeaderFields().get("Set-Cookie").get(0).split(";")[0];
httppost.addHeader("Cookie", fullCookie);
httppost.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:57.0) Gecko/20100101 Firefox/57.0");
httppost.addHeader("Accept", "*/*");
httppost.setEntity(entity);
CloseableHttpResponse execute = httpsclient.execute(httppost);
PHP:
> POST /auth/register HTTP/1.1
Host: xxx
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:57.0) Gecko/20100101 Firefox/57.0
Accept: */*
Cookie: XSRF-TOKEN=eyJpdiI6Im4zSXNHanBpM1FmXC9oZ0dEeFZFbElRPT0iLCJ2YWx1ZSI6Inh2S2FKSktQMGFxREMwVU5KZHkzSVEzaXFyVnNWdEpiQ1IzVFd4Y3c3RWFxQXV6YXFRaFNuQlBSU2M5bEs5azh2dG9zSjFoQWlNVW00dGgzeW1IeFhRPT0iLCJtYWMiOiI4MTUwZTk3ZDNkZDMyOTkxMjRkNjRhY2I5MjEzMDZmNTk5NzUwYjA5NDY3YmY0OWQ4YzQ1NmMxNTVjZDIwNzNkIn0%3D; laravel_session=eyJpdiI6IldnbGd1STlUSVZXc0NFbWZLTVhGZEE9PSIsInZhbHVlIjoiRDBndzlSZFJLUlZHYWdJWmppZmNCOWRYV2liNnV1NFJkMzNoNEpyVGRBaXlEUm94MzNSbmZ4YVdDeHM0OTNNa21qZmQ1Tjd4UVJrK2pYS3BUQUhsbFE9PSIsIm1hYyI6ImZkNTBmZjYxOTc0ZmUxNzIzZTNlOTBkYWJmMzBkODhkODkxNTk1Mjc5Nzg5MTI5NmJkYzJlYzBjOTEyMGM0OTUifQ%3D%3D
Content-Length: 718
Expect: 100-continue
Content-Type: multipart/form-data; boundary=------------------------e939a893b45ae97c
< HTTP/1.1 100 Continue
< HTTP/1.1 302 Found
< Server: nginx/1.10.3
< Content-Type: text/html; charset=UTF-8
< Transfer-Encoding: chunked
< Connection: keep-alive
< Cache-Control: no-cache
...
卷曲选项:
curl_setopt($ch, CURLOPT_URL, 'https://xxx/auth/register');
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:57.0) Gecko/20100101 Firefox/57.0');
curl_setopt($ch, CURLOPT_COOKIEFILE, __DIR__ . '.\cookiejar');
curl_setopt($ch, CURLOPT_COOKIEJAR, __DIR__ . '.\cookiejar');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postfields);
答案 0 :(得分:5)
如果您的服务器期待Content-Type: multipart/form-data
,那么您应该使用MultipartEntityBuilder
而不是UrlEncodedFormEntity
。
您的实体创建代码可能类似于
HttpEntity entity = MultipartEntityBuilder
.create()
.addTextBody("username", "jnfjkwejf")
.addTextBody("_token", _token)
.addTextBody("domain", "xxx")
.addTextBody("password", "qweqweqwe")
.addTextBody("password_confirmation", "qweqweqwe")
.addTextBody("captcha", captcha)
.build();
请参阅此链接以获取更多详细信息。 Apache HttpClient making multipart form post
更新 - 还有一点。
在Java情况下,您的Cookie标头看起来不正确。 cookie对应该用分号和空格('; '
)分隔。你的java案例中缺少空格。参考 - https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cookie
答案 1 :(得分:2)
curl可以使用两种编码中的任何一种,就像php或java一样,只需要正确配置请求类型。
urlencoded是旧式的multipart是块上的新小子,java必须能够生成两者,或许找一个新的java例子?另外,为什么不尝试自己构建实际请求并发送您需要发送的实际字节,方法是每个字节自己创建一个请求? 认为这是一个学习练习。
为了调试服务器发送500错误的原因,我建议您阅读服务器的源代码并阅读服务器的日志,它可能只是喜欢新的做事方式。
不过我喜欢旧方式,我喜欢简单。它过去很简单,一个POST请求,在我的日子里... 现在,新的方式,感觉浪费,字节太多,数据太少。