安卓与vue混合开发请求跨域处理新思路
一般处理方式要么后端处理允许CROS资源共享,要么配置nginx代理转发请求,但是混合开发的vue是在本地跑的,如果遇上后端不能开放跨域的情况,那就只能通过jsBridge通过原生去调接口,但是之前翻文档的时候,发现了android webview可以拦截每次请求,那如果将拦截下来的请求判断一下是不是OPTIONS请求,是的话直接放行,是不是也可以实现跨域?
webView.setWebViewClient(new WebViewClient() {
//拦截OPTIONS请求,添加token,使预检请求通过
@Nullable
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
if(!request.getUrl().toString().startsWith("替换为需要筛选的url") || !request.getMethod().equals("OPTIONS")) {
if (request == null || request.getUrl() == null || !request.getUrl().getScheme().equalsIgnoreCase("file")) {
return super.shouldInterceptRequest(view, request);
}
if (/** 进一步细化筛选条件 **/true) {
try {
URL urlPath = new URL(request.getUrl().toString().replace("file", "https"));
// URL urlPath = new URL(request.getUrl().toString().replace("file", "https"));
HttpsURLConnection urlConnection = (HttpsURLConnection) urlPath.openConnection();
//忽略证书
HTTPSUtils.trustAllHttpsCertificates();
//复制参数
for (Map.Entry<String, String> entry : request.getRequestHeaders().entrySet()) {
urlConnection.setRequestProperty(entry.getKey(), entry.getValue());
}
//设置请求方式
urlConnection.setRequestMethod(request.getMethod());
// urlConnection.setRequestProperty("Authorization", UserHelper.get().getAccessToken());
String contentType = urlConnection.getContentType();
String encoding = urlConnection.getContentEncoding();
InputStream inputStream;
int code = urlConnection.getResponseCode();
if (code == 200) {
inputStream = urlConnection.getInputStream(); // 得到网络返回的正确输入流
} else {
inputStream = urlConnection.getErrorStream(); // 得到网络返回的错误输入流
}
WebResourceResponse webResourceResponse = new WebResourceResponse(contentType, encoding, inputStream);
// urlConnection.disconnect();
// inputStream.close();//inputStream不能关闭,https://blog.csdn.net/y1962475006/article/details/84895173
return webResourceResponse;
} catch (MalformedURLException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
return super.shouldInterceptRequest(view, request);
}
try {
URL urlPath = new URL(request.getUrl().toString());
HttpsURLConnection urlConnection = (HttpsURLConnection)urlPath.openConnection();
//忽略证书
HTTPSUtils.trustAllHttpsCertificates();
for (Map.Entry<String, String> entry :request.getRequestHeaders().entrySet()) {
urlConnection.setRequestProperty(entry.getKey(), entry.getValue());
}
urlConnection.setRequestMethod(request.getMethod());
urlConnection.setRequestProperty("Authorization", UserHelper.get().getAccessToken());
String contentType = urlConnection.getContentType();
String encoding = urlConnection.getContentEncoding();
InputStream inputStream;
int code = urlConnection.getResponseCode();
if (code == 200) {
inputStream = urlConnection.getInputStream(); // 得到网络返回的正确输入流
} else {
//token过期,刷新或者退出到登录页
// if(code == 401){
//
// }
inputStream = urlConnection.getErrorStream(); // 得到网络返回的错误输入流
}
//将OPTIONS的返回结果原样返回,或者也可以把所有的OPTIONS全部返回200,这样直接放行所有的OPTIONS请求
// 1、OPTIONS全部放行,这样token过期的处理集中到h5处理
WebResourceResponse webResourceResponse = new WebResourceResponse(contentType, encoding, null);
Map<String, String> responseHeaders = new HashMap<>();
webResourceResponse.setStatusCodeAndReasonPhrase(200, "request success!!!");
responseHeaders.put("Access-Control-Allow-Credentials", "true");
responseHeaders.put("Access-Control-Allow-Methods", "OPTIONS, GET, PUT, POST, DELETE");
responseHeaders.put("Access-Control-Allow-Origin", "*");
responseHeaders.put("Access-Control-Allow-Headers", "*");
// 2、响应原样返回,token过期的处理集中到上面处理
// WebResourceResponse webResourceResponse = new WebResourceResponse(contentType, encoding, inputStream);
// Map<String, String> responseHeaders = new HashMap<>();
// for (Map.Entry<String, List<String>> entry :urlConnection.getHeaderFields().entrySet()) {
// responseHeaders.put(entry.getKey(), entry.getValue().get(0));
// }
// responseHeaders.put("Access-Control-Allow-Headers", "*");//XToken,响应头不包含XToken,导致后续接口包含Xtoken的请求都请求失败,直接设为全部
webResourceResponse.setResponseHeaders(responseHeaders);
urlConnection.disconnect();
// inputStream.close();//inputStream不能关闭
return webResourceResponse;
} catch (MalformedURLException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
//以下是其他方法
....
}