HttpClient进行http请求出现403 |
您所在的位置:网站首页 › curl报错403 › HttpClient进行http请求出现403 |
使用HttpClient进行http请求时,出现403错误,搜到一些解决办法,记录下来。 第一种是http请求: 原文地址: http://blog.csdn.net/yue_pengcheng/article/details/10820231 Android,使用Apache HttpClient 和 HttpURLConnection 访问服务器接口,被拒绝,返回403 forbidden,然而同样的URL使用浏览器访问是正常的。 (注:本篇问题仅限于Http请求,若是Https请求可先检查SSL设置) 查了下关于403的几种可能性: 403 禁止访问:访问被拒绝 403.1 禁止访问:执行访问被拒绝 403.2 禁止访问:读取访问被拒绝 403.3 禁止访问:写入访问被拒绝 403.4 禁止访问:需要使用 SSL 查看该资源 403.5 禁止访问:需要使用 SSL 128 查看该资源 403.6 禁止访问:客户端的 IP 地址被拒绝 403.7 禁止访问:需要 SSL 客户端证书 403.8 禁止访问:客户端的 DNS 名称被拒绝 403.9 禁止访问:太多客户端试图连接到 Web 服务器 403.10 禁止访问:Web 服务器配置为拒绝执行访问 403.11 禁止访问:密码已更改 403.12 禁止访问:服务器证书映射器拒绝了客户端证书访问 403.13 禁止访问:客户端证书已在 Web 服务器上吊销 403.14 禁止访问:在 Web 服务器上已拒绝目录列表 403.15 禁止访问:Web 服务器已超过客户端访问许可证限制 403.16 禁止访问:客户端证书格式错误或未被 Web 服务器信任 403.17 禁止访问:客户端证书已经到期或者尚未生效 403.18 禁止访问:无法在当前应用程序池中执行请求的URL 403.19 禁止访问:无法在该应用程序池中为客户端执行CGI 403.20 禁止访问:Passport 登录失败 通过一系列操作,排除法将问题锁定在Http头字段的问题上。使用HttpWatch 检测浏览器的头字段设置,发现User-Agent字段可能存在问题。
打印源生的的User-Agent字段是null,尝试设置UA字段,看下IE浏览器User-Agent的格式: "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:0.9.4)" HttpUriRequest.setHeader("User-Agent",“Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:0.9.4)”); (注:HttpUriRequest类是HttpGet 和 HttpPost的父类) 可以正常访问了。 另外:我们可以使用User-Agent字段做一些统计信息的提交,只要遵从特定格式即可,例如: “Mozilla/5.0 (Android/4.0.3; HUAWEI U9200; IMEI/111111111111111; IMSI/111111111111)” 可以根据自己的需要添加特定字段。 自此我的问题解决了。
关于403,还存在另外一种可能,Referer 字段,某些网站做了盗链的限制,仅限于本网站链接导入的网址才可以访问,这时我们可以设置Referer字段: HttpUriRequest.setHeader("Referer","http://,,,"); 使用HttpURLConnection访问的同学可以是用 conn.setRequestProperty("Referer", "http://,,,"); value字段可以是访问接口的域名地址。
相比起接口,图片和文件防止盗链的限制更多一些,也可以在下载图片或其他类型文件的请求中添加Referer头字段,问题就解决啦。
第二篇是关于https的请求: http://my.oschina.net/atearsan/blog/205517 出现的过程 最近在用程序模拟一个web站的https登录,然后进行一些后续操作的小玩意。先使用java程序写测试代码,测试通过移植到android。 java基于httpclient-4.3.1.jar开发。 android端使用自带的HttpClient。(sdk版本14) 代码移植到android环境,https请求出现403(请求被拒绝),Google N久找不到答案 - -。但是java一次又一次都能成功! 处理方法最终换jar!使用commons-httpclient-3.1.jar!业务逻辑不变,程序测试通过! 我!很!忧!伤!(java端可以,android端不行。) (jar是从http://git.oschina.net/atearsan/android-app/tree/master/libs里下的- -,我懒,直接用osc那边的) 同样是403,其他的一些可能情况 我这个情况可能特殊,Google时也发现了其他的一些情况,顺便记录下。 1. 缺少header参数. 常见的如下: ? 1 2 3 4 post.addHeader( "Referer" , xx); post.addHeader( "Content-Type" , "application/x-www-form-urlencoded; charset=UTF-8" ); post.addHeader( "User-Agent" , "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63" ); post.addHeader( "Host" , xx);
2. 缺少cookie信息. 这个就需要分析实际的请求了。可以借助一些工具分析(http/https/tcp)请求链接,常见的工具有: Fiddler Wireshark 还有直接浏览器调式也行,但是可能不够用,请求过程不够清晰 java端和android端部分关键代码 不知道贴出来是否有实际用处,先贴出来吧。 java端: ? 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 36 37 38 39 40 41 42 public void login() { try { List loginParams = new ArrayList(); loginParams.add( new BasicNameValuePair( "appuri" , appuri)); loginParams.add( new BasicNameValuePair( "useruri" , useruri)); loginParams.add( new BasicNameValuePair( "service" , service)); loginParams.add( new BasicNameValuePair( "sid" , null )); loginParams.add( new BasicNameValuePair( "uname" , name)); loginParams.add( new BasicNameValuePair( "action" , action)); loginParams.add( new BasicNameValuePair( "pwd" , password)); HttpPost post = new HttpPost(loginURL); post.addHeader( "Referer" , referer); post.addHeader( "Content-Type" , "application/x-www-form-urlencoded; charset=UTF-8" ); post.addHeader( "User-Agent" , "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63" ); post.addHeader( "Host" , "xxxxxxxxx" ); post.setEntity( new UrlEncodedFormEntity(loginParams, HTTP.UTF_8)); // 发送登录请求 HttpResponse response = httpClient.execute(post); if (response.getStatusLine().getStatusCode() == HttpStatus.SC_MOVED_TEMPORARILY) { post.releaseConnection(); // 获取重定向地址 String location = getLocation(response); if (! "" .equals(location)) { String signURL = getSignURL(location); if (! "" .equals(signURL)) { signIn(signURL); } else { System.out.println( "signURL为空" ); } } else { System.out.println( "location为空" ); } } else { System.out.println( "登录出错了" ); } } catch (Exception e) { e.printStackTrace(); } }
android端的实现: ? 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 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 public void login() { try { /* List loginParams = new ArrayList(); loginParams.add(new BasicNameValuePair("appuri", appuri)); loginParams.add(new BasicNameValuePair("useruri", useruri)); loginParams.add(new BasicNameValuePair("service", service)); loginParams.add(new BasicNameValuePair("sid", "")); loginParams.add(new BasicNameValuePair("uname", name)); loginParams.add(new BasicNameValuePair("action", action)); loginParams.add(new BasicNameValuePair("pwd", password)); HttpPost post = new HttpPost(loginURL); post.addHeader("Referer", referer); post.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8"); post.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63"); post.addHeader("Host", "xxx"); post.setEntity(new UrlEncodedFormEntity(loginParams, HTTP.UTF_8)); HttpResponse response = httpClient.execute(post); */ HttpClient cc = new HttpClient(); PostMethod pm = new PostMethod(loginURL); org.apache.commons.httpclient.NameValuePair[] parametersBody = { new org.apache.commons.httpclient.NameValuePair( "appuri" , appuri), new org.apache.commons.httpclient.NameValuePair( "useruri" , useruri), new org.apache.commons.httpclient.NameValuePair( "service" , service), new org.apache.commons.httpclient.NameValuePair( "sid" , "" ), new org.apache.commons.httpclient.NameValuePair( "uname" , name), new org.apache.commons.httpclient.NameValuePair( "action" , action), new org.apache.commons.httpclient.NameValuePair( "pwd" , password) }; pm.setRequestBody(parametersBody); pm.setRequestHeader( "Referer" , referer); pm.setRequestHeader( "Content-Type" , "application/x-www-form-urlencoded; charset=UTF-8" ); pm.setRequestHeader( "User-Agent" , "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63" ); pm.setRequestHeader( "Host" , "xxx" ); // int statusCode = response.getStatusLine().getStatusCode(); int statusCode = cc.executeMethod(pm); // 登录请求 if (statusCode == HttpStatus.SC_MOVED_TEMPORARILY) { String location = getLocation(pm); // 获取重定向地址 // String location = getLocation(response); if (!TUtil.EMPTY.equals(location)) { String signURL = getSignURL(location); if (!TUtil.EMPTY.equals(signURL)) { signIn(signURL); } else { String log = "获取签到地址失败" ; super .notification(TUtil.TYPE_CM_E_CODE, log); } } else { String log = "获取重定向地址失败" ; super .notification(TUtil.TYPE_CM_E_CODE, log); } } else { String log = "登录失败.状态码:" +statusCode; super .notification(TUtil.TYPE_CM_E_CODE, log); } } catch (Exception e) { Log.e(e); String log = "登录异常:" +e.getMessage(); super .notification(TUtil.TYPE_CM_E_CODE, log); } }
// java端和android代码对比结果: // 代码真的没啥差异,android端被注释的那些就是使用自带的HttpClient,但是偏偏登录请求一直是403. // 换成基于commons-httpclient-3.1.jar的HttpClient,没问题了! // // 我还有个问题就是:android sdk 14 自带的apche HttpClient是什么年代的版本...??? java端4.3没问题- - 最后检查才发现:是我的http地址写错了,不是上面的问题,尴尬。 |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |