selenium利用executeScript执行Post
【摘要】 问题场景:同事使用htmlunit发送post请求(负载json)请求一个预期json数据,返回始终和预期不一致;问题分析过程:使用httpclient进行post请求,header中直接附加浏览器中的cookie和其他,content-type未设置时http状态500,content-type设置后状态204,初步判断可能是有连接session相关的判断;使用selenium,设置Hea...
问题场景:
同事使用htmlunit发送post请求(负载json)请求一个预期json数据,返回始终和预期不一致;
问题分析过程:
使用httpclient进行post请求,header中直接附加浏览器中的cookie和其他,content-type未设置时http状态500,content-type设置后状态204,初步判断可能是有连接session相关的判断;
使用selenium,设置Headless为false,进行目标网站登录操作,然后由于selenium没有直接post的方法,所以使用executeScript发送相关请求
String js= "function getRet(){\r\n" +
" var datas = null;\r\n" +
" XXX.doPost({\r\n" +
" async:false,\r\n" +
" url:'目标地址',\r\n" +
" data:{json负载},\r\n" +
" success : function(datass){\r\n" +
" datas = datass;\r\n" +
" }\r\n" +
" });\r\n" +
" return datas;\r\n" +
"}\r\n" +
"return getRet();";
Object ret = (Object)jsExecutor.executeScript(js);
结果符合预期
3.同事使用的是htmlunit
由于目标网站的登录会跳转sso域然后返回存在多次重定向,
设置webClient.getOptions().setRedirectEnabled(true);
HtmlPage retPage = button.click();
Thread.sleep(10000);//区别于synchronized (homePage) {homePage.wait(25000);}和client.waitForBackgroundJavaScript(30000)
//由于存在多次重定向,这个等待是必要的
PrintStream originalOut = System.out;
PrintStream fileOut = new PrintStream("./out111.txt");
System.setOut(fileOut);
System.out.println(((HtmlPage) webClient.getCurrentWindow().getEnclosedPage()).asXml());//获取当前页面而不使用前面的Page变量,因为存在多次重定向
System.setOut(originalOut);
经过修改后,第一步的日志结果符合预期,第二步post请求
1.使用htmlunit的post
WebRequest requestSettings = new WebRequest(url, HttpMethod.POST)
requestSettings.setAdditionalHeader("Content-Type","application/json");
requestSettings.setAdditionalHeader("Accept", "application/json");
requestSettings.setRequestBody(param);
由于和登录共用的一个webclient对象,就没必要设置cookie头了;
测试结果,始终返回一个不符合预期的html结果
2.使用executeJavaScript获取,
js最后的return需要修改为JSON.stringify(getRet()),
ScriptResult result = ((HtmlPage) webClient.getCurrentWindow().getEnclosedPage()).executeJavaScript(js);//使用当前页,即登录跳转最终页
Thread.sleep(10000);//需不需要等待,没有测试
Object rt = result.getJavaScriptResult();
fileOut = new PrintStream("./out222.txt");
System.setOut(fileOut);
System.out.println(rt.toString());
System.setOut(originalOut);
结果符合预期
/*-------------------------------------------------------------------------------------------*/
后面我又采用httpclient的方式继续做了测试, 前面说到可能是有连接session相关的判断,那么考虑 登录和post共用一个httpclient和httpcontent,
CloseableHttpClient httpClient = HttpClients.createDefault();
CookieStore cookieStore = new BasicCookieStore();
HttpContext httpContext = new BasicHttpContext();
httpContext.setAttribute(HttpClientContext.COOKIE_STORE, cookieStore);
DoLoginD(httpClient,"xxx",Base64.decode("xxxxx"),httpContext);//使用同一个httpclient和httpContext
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(2*5000)
.setConnectionRequestTimeout(2*5000)
.setSocketTimeout(2*5000)
.setRedirectsEnabled(true)
.build();
HttpPost request = new HttpPost(url);
request.setConfig(requestConfig);
request.setHeader("Accept", "application/json, text/plain, */*"); //, text/javascript, */*; q=0.01
request.setHeader("Content-Type","application/json;charset=utf-8");
StringEntity postStr = new StringEntity(postBody,ContentType.APPLICATION_JSON);//这个ContentType.APPLICATION_JSON需要尤为注意,前面204很大程度是这个没设置的问题
request.setEntity(postStr);
HttpResponse response = httpClient.execute(request,httpContext);
if(response.getStatusLine().getStatusCode() == 200){
HttpEntity entity = response.getEntity();
if (entity != null) {
long len = entity.getContentLength();
if (len != -1 && len < 2048)
result = EntityUtils.toString(entity);
else
{
StringBuffer sb = new StringBuffer(1024 * 512);
BufferedReader in = new BufferedReader(
new InputStreamReader(entity.getContent(), encoding));
String line = null;
while ((line = in.readLine()) != null)
{
sb.append(line);
}
result = sb.toString();
}
System.out.println("Fetched data length: " + (result.length() / 1000) + " KB");
EntityUtils.consume(entity);
}
} else {
System.out.println("response code"+response.getStatusLine().getStatusCode());
HttpEntity entity = response.getEntity();
String test = EntityUtils.toString(entity);
System.out.println(test);
}
反思:
前面的204的原因应该主要就是ContentType.APPLICATION_JSON未设置导致的;
参考:
https://stackoverflow.com/questions/12059278/how-to-post-json-request-using-apache-httpclient
【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
作者其他文章
评论(0)