Android WebView 는 동적 수정 js 를 통 해 post 요청 매개 변수 인 스 턴 스 를 차단 합 니 다.
사용자 가 제출 단 추 를 눌 렀 을 때 사용자 가 제출 한 데 이 터 를 차단 해 야 합 니 다.
질문
1.페이지 는 자신의 전단 에서 만 든 것 이 아니 므 로 웹 페이지 의 코드 를 수정 할 수 없습니다.
2.차단 할 요청 은 get 요청 이 아니 라 post 요청 입 니 다.
해결 포인트:
웹 뷰 클 라 이언 트 의 shouldInterceptRequest 를 다시 쓰 는 방법
1.이 방법 은 API 21 이후 에 나타 난 것 입 니 다.그리고 유행 이 지난 방법 도 다시 써 야 합 니 다.잊 지 마 세 요!
2.웹 페이지 를 불 러 올 때 모든 자원 은 shouldInterceptRequest 라 는 방법 을 거 칩 니 다.shouldInterceptRequest 와 패키지 도구(Fidder,Charles)를 통 해 정 보 를 얻 고 싶 은 사이트 주소 와 자원 파일 을 얻 을 수 있 습 니 다.
3.이 방법 은 하위 스 레 드 에서 실 행 됩 니 다.UI 를 업데이트 하려 면 스 레 드 를 전환 하 십시오.
해결 방안:
나 는 여기에서 두 가지 해결 방안 을 찾 았 다.
방안 A:js 에 정통 한 어른 들 에 게 적합 합 니 다.
1.페이지 에 있 는 버튼 의 클릭 이 벤트 를 차단 하고 이 벤트 를 클릭 하 는 동작 을 교체 합 니 다.
$('#J_submit').off('click'); //1. id J_submit
$('#J_submit').on('click',function(){ //2. id J_submit , function
if ($(this).hasClass("btn-disabled")) { // ----- , -----
return;
}
try {
trackDealerEvent('dlr_order_page_form_submit_click', {
'esfrom': _mediaId,
'business': 'songshu',
'series': _seriesId,
'city': _cityId
});
} catch (e) {
console.log(e);
} // ----- , -----
var pageFormData = validateAllField(alertDiv);
if (pageFormData) { //3.
$.ajax({ //4.ajax
url: 'https://gouche.jxedt.com/gouche/clue/submit',
data: {
cityid: _cityId,
brandid: _brandId,
seriesid: _seriesId,
classesid: _specId,
name: $("[name='userName']").val(),
phone: $('#phoneNumber').val(),
type: 4
}
});
postOrder(pageFormData);
}
})
2.동적 으로 js 코드 불 러 오기
mCommonWebView.setCommonWebViewClient(new CommonWebViewClient() { // WebViewClient
@Override
public void onPageFinished(WebView view, String url) { // onPageFinished
super.onPageFinished(view, url);
// js
runRemoteJs(Constant.QueryCarPrice.loadJsUrl_CarHome);
}
private void runJs(String remoteJs){ // js
if(TextUtils.isEmpty(remoteJs)) {
return;
}
String js = "javascript:"; // : js
js+= "var script = document.createElement('script');"; // : script
js+= "script.type = 'text/javascript';";
js+=remoteJs;
mCommonWebView.callJsFunction(js); // js
}
private void runRemoteJs(String url) {// , js ,
RxRequest<String> request = new RxRequest<String>()
.setUrl(url)
.setMethod(Request.Method.GET);
RxHttpEngineWrapper.commonExec(request)
.subscribeOn(AndroidSchedulers.mainThread())
.subscribe(new UtilsRx.DefaultSubscriber<String>(){
@Override
public void onNext(String s) {
runJs(s);
}
});
}
});
3.그 때 는 페이지 의 js 를 전면 에 크게 수정 하면 됩 니 다.이 프로젝트 의 구덩이:
1.불 러 올 js 코드 에는 script 노드 가 포함 되 어 있 지 않 습 니 다.
2.불 러 올 js 코드 에 설명 이 없 음
3.불 러 올 js 코드 에 반드시 점 수 를 붙 여야 한다
*위의 세 가지 요 구 를 만족 시 키 지 못 하면 불 러 올 js 가 제대로 실행 되 지 않 습 니 다.
방안 B:네 이 티 브 안 드 로 이 드 방식 은 이전 방안 에 비해 번 거 로 운 방안 입 니 다.
1.shouldInterceptRequest 를 다시 써 서 자원 차단
2.제3자 웹 페이지 에서 인터넷 요청 을 하 는 js 페이지 를 다운로드(웹 페이지 의 모든 다운로드,인터넷 요청 을 하 는 js 페이지 를 찾 는 것)하여 js 페이지 를 수정
3.처 리 된 js 페이지 를 로 컬 로 불 러 옵 니 다.나중에 불 러 올 때 로 컬 js 를 이용 하여 제3자 js 를 교체 합 니 다.(로 컬 js 페이지 에 webview 와 소통 하 는 다 리 를 추가 하 겠 습 니 다)
// , , ,
// WebView
private void initWebView() {
mWebView.getSettings().setDomStorageEnabled(true);
mWebView.getSettings().setDefaultTextEncodingName("utf-8");
if(Build.VERSION.SDK_INT >=21){//Added in API level 21
mWebView.getSettings().setMixedContentMode(android.webkit.WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
}
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.getSettings().setUseWideViewPort(true); // webview , html
mWebView.getSettings().setLoadWithOverviewMode(true);
mWebView.getSettings().setGeolocationEnabled(true);
mWebView.getSettings().setAllowFileAccess(true);
if (Build.VERSION.SDK_INT >= 16) {
// Webview
mWebView.getSettings().setAllowFileAccessFromFileURLs(false);
mWebView.getSettings().setAllowUniversalAccessFromFileURLs(false);
}
mWebView.getSettings().setPluginState(WebSettings.PluginState.ON);
if (Build.VERSION.SDK_INT >= 11) {
mWebView.getSettings().setAllowContentAccess(true);
}
mWebView.loadUrl(currUrl);
mWebView.setWebViewClient(new MyWebViewClient());
// js
mWebView.addJavascriptInterface(new StubClass(),"stub");
}
public class MyWebViewClient extends WebViewClient {
/* shouldInterceptRequest , demo, */
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
// Map
HashMap<String,String> params;
Uri uri=Uri.parse(url); // Uri
if (rightUrl(uri.toString())) {
/*get */
params=paramForGET(uri);
/* ,post */
/*
* post :
* js , js
* js ,
*/
if (uri.toString().contains("index.js")) { // js
try {
//WebResourceResponse String mimeType: String encoding: InputStream input:
return new WebResourceResponse("application/x-javascript","UTF-8",getAssets().open("index.js"));
} catch (IOException e) {
e.printStackTrace();
}
}
}
return super.shouldInterceptRequest(view, url);
}
//API21 21
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
// Map
HashMap<String,String> params;
String method=request.getMethod(); //
Map<String, String> requestHeaders = request.getRequestHeaders(); //
Uri uri=request.getUrl(); // Uri
if (rightUrl(uri.toString())) {
/*get */
params=paramForGET(uri);
/* ,post */
/*
* post :
* js , js
* js ,
*/
if (uri.toString().contains("index.js")) { // js
try {
//WebResourceResponse String mimeType: String encoding: InputStream input:
return new WebResourceResponse("application/x-javascript","UTF-8",getAssets().open("index.js"));
} catch (IOException e) {
e.printStackTrace();
}
}
}
return super.shouldInterceptRequest(view, request);
}
private boolean rightUrl(String url){
if (url.contains(COLLECT_URL)) //
return true;
return false;
}
private HashMap<String,String> paramForGET(Uri uri){
HashMap<String,String> params=new HashMap<>();
Set<String> paramNames = uri.getQueryParameterNames(); // get
/* , */
for (String param : paramNames) {
params.put(param,uri.getQueryParameter(param)); //
}
return params;
}
}
public class StubClass{
@JavascriptInterface
public void getData(String json){
Log.i("xxx","json -> "+json);
}
}
이것 은 제 지역 의 js 입 니 다.원래 의 js 를 수정 하고 안 드 로 이 드 와 통신 하 는 다 리 를 추가 하여 데 이 터 를 캡 처 했 습 니 다.추가 지식:android WebView 사용 Post 요청 및 브 라 우 저 폭탄 상자 설정
여기 서 주의해 야 할 것 은 post 요청 매개 변 수 는 byte 배열 만 전송 할 수 있 고 문자열 형식의 byte 배열 이 어야 합 니 다.그 중의 key 는 배경 서버 에서 key 를 받 습 니 다.배경 에 key 가 어떤 값 인지 규정 하고 임의로 변경 할 수 없습니다.key=value 형식 이 없 거나 key 가 정확 하지 않 으 면 데이터 웹 페이지 를 열 수 없습니다.
다음 코드 는 initWebView()방법 을 직접 보시 면 됩 니 다.
package com.xxxxx.xxx.activity.banksign;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.webkit.JsResult;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import com.xinzong.etc.R;
import com.xinzong.xx.base.BaseGestureActivty;
import com.xinzong.xxx.utils.ShowReloadUtil;
/**
*
* @author
*
*/
public class WebViewActivity extends BaseGestureActivty implements OnClickListener{
private ShowReloadUtil reloadUtil;
private String url = "http://120.1.1.1/xx/xxxx";
private WebView webView;
private String urlParameter = "";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sign_webview);
findViewById(R.id.ibBack).setOnClickListener(this);
//
urlParameter = getIntent().getStringExtra("urlParameter");
Log.i("TAG", urlParameter);
//
reloadUtil = new ShowReloadUtil(this);
reloadUtil.setReloadView(this, R.id.ll_show_data_mc,
R.id.rl_reload_parent_mc);
// , webview
refresh();
}
private void refresh() {
if(isNetworkConnected()){
findView(R.id.webview1).setVisibility(View.VISIBLE);
reloadUtil.showDataView();
initWebView();
}else{
findView(R.id.webview1).setVisibility(View.GONE);
reloadUtil.showReload();
}
}
private void initWebView() {
webView = (WebView) findViewById(R.id.webview1);
// webview
// javascript
WebSettings settings = webView.getSettings();
settings.setJavaScriptEnabled(true);// javaScript
settings.setDefaultTextEncodingName("utf-8");//
settings.setJavaScriptCanOpenWindowsAutomatically(true);
Log.d("TAG", "url:"+url);
//post ( , get ,key=value, & )
urlParameter = "JSONpriKey=" +urlParameter;
webView.postUrl(url, urlParameter.getBytes());
// webView.loadUrl(url);//get
webView.setWebChromeClient(new MyWebChromeClient());//
// WebView , WebView
webView.setWebViewClient(new WebViewClient(){
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// true WebView , false
Log.d("TAG", "url:"+url);
view.loadUrl(url);
return true;
}
@Override
public void onPageStarted(WebView view, String url,
Bitmap favicon) {
Log.d("TAG", "onPageStarted--url:"+url);
// ,
if(url.endsWith("http://120.1.1.1/xxx/xx/xxx")){
finish();
}
super.onPageStarted(view, url, favicon);
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
}
});
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.btnReload) {// ‘ '
reloadUtil.showClickloadingView();
Log.d("TAG", "RELOAD");
if (this.isNetworkConnected()) {
webView.loadUrl(url);
} else {
reloadUtil.showReload();
}
}else if(v.getId() == R.id.ibBack){
if(webView !=null && webView.canGoBack()){
webView.goBack();
}else{
finish();
}
}
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if(keyCode == KeyEvent.KEYCODE_BACK && webView !=null && webView.canGoBack()){
webView.goBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
/**
*
*
* @author Administrator
*
*/
final class MyWebChromeClient extends WebChromeClient {
@Override
public boolean onJsConfirm(WebView view, String url, String message,
final JsResult result) {
new AlertDialog.Builder(CTX)
.setTitle("App Titler")
.setMessage(message)
.setPositiveButton(android.R.string.ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int which) {
result.confirm();
}
})
.setNegativeButton(android.R.string.cancel,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int which) {
result.cancel();
}
}).create().show();
return true;
}
}
}
이상 의 안 드 로 이 드 웹 뷰 는 동적 수정 js 를 통 해 post 요청 매개 변수 인 스 턴 스 를 차단 하 는 것 이 바로 작은 편집 이 여러분 에 게 공유 하 는 모든 내용 입 니 다.참고 하 시 기 를 바 랍 니 다.여러분 들 이 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Bitrise에서 배포 어플리케이션 설정 테스트하기이 글은 Bitrise 광고 달력의 23일째 글입니다. 자체 또는 당사 등에서 Bitrise 구축 서비스를 사용합니다. 그나저나 며칠 전 Bitrise User Group Meetup #3에서 아래 슬라이드를 발표했...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.