写一个代理工具服务,所有的请求经过此服务转发到不同的服务,可以统一处理跨域问题,只要允许这个服务的请求即可。
中转工具: https://blog.csdn.net/xxssyyyyssxx/article/details/72954499
1. 用户浏览器自己放开跨域限制: https://www.jianshu.com/p/2db73311fcbe
2. nginx部分一些对域名的操作: https://segmentfault.com/a/1190000003710973?_ea=663456
3. 使用插件,需要改写插件或者中转服务开发,目前选择中转服务,以下是一个市场上的插件:
ApiDebug工具:https://gitee.com/CrapApi/ApiDebug
4. 跨域的说明,如jsonp只支持get方式 https://blog.csdn.net/wonking666/article/details/79159180
cors方式: http://www.ruanyifeng.com/blog/2016/04/cors.html
浏览器和服务器实现跨域(CORS)判定的原理:https://segmentfault.com/a/1190000003710973?_ea=663456
Controller类名上方添加@CrossOrigin 注解通过此方式注解则Controller中的所有通过@RequestMapping注解的方法都可以进行跨域请求。 代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
Filter,我们在写springMVC的时候,更喜欢的方式是通过@ResponseBody给返回对象进行封装直接返回给前端,这样简单而且容易。 如果使用@ResponseBody就不能使用第一种方法了,所有就使用filter给所有的请求都封装一下 <filter> <filter-name>corsBean</filter-name> <filter-class>com.ximalaya.mobile.user.filter.HeadersCORSFilter</filter-class> </filter> <filter-mapping> <filter-name>corsBean</filter-name> <url-pattern>*</url-pattern> </filter-mapping> /** * 解决H5页面的跨域问题 * @author chong.wang@ximalaya.com * @date 2020/4/29 下午3:34 */ public class HeadersCORSFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { // TODO Auto-generated method stub } @Override public void doFilter(ServletRequest request, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException { HttpServletResponse response = (HttpServletResponse) servletResponse; response.setHeader("Access-Control-Allow-Origin", "*"); response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE"); response.setHeader("Access-Control-Max-Age", "3600"); response.setHeader("Access-Control-Allow-Headers", "x-requested-with,Authorization"); response.setHeader("Access-Control-Allow-Credentials", "true"); chain.doFilter(request, servletResponse); } @Override public void destroy() { // TODO Auto-generated method stub } }
中转:
private static Map<String, Object> requestExcute(ApiRequestBody apiRequestBody, String restUrl, Map<String, Object> params, HttpClient httpClient) {
HttpGet httpGet = null;
HttpPost httpPost = null;
HttpPut httpPut = null;
HttpDelete httpDelete = null;
Map<String, Object> result = new HashMap<>();
HttpEntity entity = null;
HttpResponse response = null;
Long timeCost = 0L;
try {
LocalDateTime beginTime = LocalDateTime.now();
if (Constant.RequestMode_POST.equalsIgnoreCase(apiRequestBody.getRequestMode())) {
httpPost = new HttpPost(restUrl);
handleRquestHeader(apiRequestBody, httpPost);
response = getPostHttpResponse(apiRequestBody, restUrl, params, httpClient, httpPost);
} else if (Constant.RequestMode_GET.equalsIgnoreCase(apiRequestBody.getRequestMode())) {
//get方式参数方式传过来的,进行处理
restUrl = getRequestGetModeUrl(restUrl, params);
httpGet = new HttpGet(restUrl);
handleRquestHeader(apiRequestBody, httpGet);
log.info("RequestMode_GET full restUrl:" + restUrl);
response = httpClient.execute(httpGet);
} else if (Constant.RequestMode_PUT.equalsIgnoreCase(apiRequestBody.getRequestMode())) {
//get方式参数方式传过来的,进行处理
restUrl = getRequestGetModeUrl(restUrl, params);
httpPut = new HttpPut(restUrl);
handleRquestHeader(apiRequestBody, httpPut);
log.info("RequestMode_PUT full restUrl:" + restUrl);
response = httpClient.execute(httpGet);
} else if (Constant.RequestMode_DELETE.equalsIgnoreCase(apiRequestBody.getRequestMode())) {
//get方式参数方式传过来的,进行处理
restUrl = getRequestGetModeUrl(restUrl, params);
httpDelete = new HttpDelete(restUrl);
handleRquestHeader(apiRequestBody, httpDelete);
log.info("RequestMode_DELETE full restUrl:" + restUrl);
response = httpClient.execute(httpGet);
}
timeCost = Duration.between(beginTime, LocalDateTime.now()).toMillis();
if (response == null) {
handleResponseError(apiRequestBody, result, entity, timeCost, 404);
}
int status = response.getStatusLine().getStatusCode();
log.info("请求restUrl:" + restUrl + "网络状态:status=" + status);
entity = response.getEntity();
if (HttpStatus.SC_OK == status) {
handleResponseOk(apiRequestBody, result, entity, response, timeCost);
} else {
handleResponseError(apiRequestBody, result, entity, timeCost, status);
}
return result;
} catch (Exception e) {
return getProxyResponseError(apiRequestBody, restUrl, params, result, timeCost, e);
} finally {
handleCloseIO(httpClient, httpGet, httpPost, httpPut, httpDelete, entity);
}
}
private static HttpResponse getPostHttpResponse(ApiRequestBody apiRequestBody, String restUrl, Map<String, Object> params, HttpClient httpClient, HttpPost httpPost) throws IOException {
HttpResponse response;
log.info("POST restUrl:" + restUrl);
// 设置参数,form格式
if (StringUtils.isEmpty(apiRequestBody.getRequestDataJson())) {
setRequestDataParams(apiRequestBody, params, httpPost);
} else {
//处理请求json数据
// requestJsonData = requestJsonData.trim().replace("\\\\n","").replace("\\\\\\","y|y").replace("\\\\","").replace("y|y","\\");
log.info("POST requestJsonData:" + apiRequestBody.getRequestDataJson());
handleRequestJsonData(apiRequestBody, httpPost);
}
response = httpClient.execute(httpPost);
return response;
}
private static Map<String, Object> getProxyResponseError(ApiRequestBody apiRequestBody, String restUrl, Map<String, Object> params, Map<String, Object> result, Long timeCost, Exception e) {
e.printStackTrace();
result.put("ResultCode", 500);
result.put("timeCost", timeCost);
result.put("ResultMsg", "请求对应服务,返回异常,请检查请求url以及入参信息,restUrl:" + restUrl + ",requestJsonData:" + apiRequestBody.getRequestDataJson() + ",params:" + JsonUtils.toJson(params));
return result;
}
private static void handleCloseIO(HttpClient httpClient, HttpGet httpGet, HttpPost httpPost, HttpPut httpPut, HttpDelete httpDelete, HttpEntity entity) {
if (null != entity) {
try {
EntityUtils.consume(entity);
} catch (IOException e) {
e.printStackTrace();
}
}
if (null != httpGet && httpGet.isAborted()) {
httpGet.abort();
}
if (null != httpPost && httpPost.isAborted()) {
httpPost.abort();
}
if (null != httpPut && httpPut.isAborted()) {
httpPut.abort();
}
if (null != httpDelete && httpDelete.isAborted()) {
httpDelete.abort();
}
if (null != httpClient) {
httpClient.getConnectionManager().shutdown();
}
}
private static void handleResponseError(ApiRequestBody apiRequestBody, Map<String, Object> result, HttpEntity entity, Long timeCost, int status) throws IOException {
String error = new String(EntityUtils.toString(entity).getBytes(apiRequestBody.getOutputCharset()), Constant.ClientOutputCharset);
String ret = "网络错误:错误代码" + status + Constant.COMMA + error;
result.put("ResultCode", status);
result.put("ResultMsg", "FAIL");
result.put("timeCost", timeCost);
result.put("Data", ret);
}
private static void handleResponseOk(ApiRequestBody apiRequestBody, Map<String, Object> result, HttpEntity entity, HttpResponse response, Long timeCost) throws IOException {
String ret = "";
if (entity != null) {
ret = new String(EntityUtils.toString(entity).getBytes(apiRequestBody.getOutputCharset()), Constant.ClientOutputCharset);
}
Header[] cookieHeader = response.getHeaders("Set-Cookie");
Header[] allHeader = response.getAllHeaders();
result.put("ResultCode", HttpStatus.SC_OK);
result.put("ResultMsg", "SUCCESS");
result.put("timeCost", timeCost);
result.put("Data", ret);
result.put("cookieHeader", cookieHeader);
result.put("allHeader", allHeader);
}
private static String getRequestGetModeUrl(String restUrl, Map<String, Object> params) {
if (params != null) {
for (Iterator iter = params.keySet().iterator(); iter.hasNext(); ) {
String name = (String) iter.next();
String value = String.valueOf(params.get(name));
if (StringUtils.isNotEmpty(name) && StringUtils.isNotEmpty(value)) {
if (restUrl.contains(Constant.QUESTION)) {
restUrl = restUrl + Constant.AND + name + Constant.EQUAL + value;
} else {
restUrl = restUrl + Constant.QUESTION + name + Constant.EQUAL + value;
}
}
}
}
return restUrl;
}
private static Map<String, String> handleRquestHeader(ApiRequestBody apiRequestBody, HttpRequestBase httpBase) {
Map<String, String> headers = new HashMap<>();
if (StringUtils.isNotEmpty(apiRequestBody.getHeaders())) {
headers = getHeaders(apiRequestBody, headers);
// 设置header
if (headers != null) {
for (Map.Entry<String, String> entry : headers.entrySet()) {
//Post请求
if (StringUtils.isNotEmpty(entry.getKey())) {
httpBase.addHeader(entry.getKey(), entry.getValue());
}
}
}
}
return headers;
}
private static Map<String, String> getHeaders(ApiRequestBody apiRequestBody, Map<String, String> headers) {
try {
JSONArray headArray = JSONArray.parseArray(apiRequestBody.getHeaders());
headers = jsonArray2Map(headArray);
} catch (Exception e) {
log.info("POST parseArray Headers error:" + e.getMessage());
}
return headers;
}
private static void handleRequestJsonData(ApiRequestBody apiRequestBody, HttpPost httpPost) throws UnsupportedEncodingException {
StringEntity reqEntity = new StringEntity(apiRequestBody.getRequestDataJson(), Constant.ContentType, apiRequestBody.getInputCharset());
reqEntity.setContentType(Constant.ContentType);
reqEntity.setContentEncoding(apiRequestBody.getInputCharset());
httpPost.setEntity(reqEntity);
}
private static void setRequestDataParams(ApiRequestBody apiRequestBody, Map<String, Object> params, HttpPost httpPost) throws UnsupportedEncodingException {
List<NameValuePair> nvps = new ArrayList<NameValuePair>();
for (Iterator iter = params.keySet().iterator(); iter.hasNext(); ) {
String name = (String) iter.next();
String value = String.valueOf(params.get(name));
if (value.contains(Constant.SQUARE_BRACKETS_PRE) && value.contains(Constant.SQUARE_BRACKETS_SUFFIX) && value.contains(Constant.COMMA)) {
String newValue = value.replace(Constant.SQUARE_BRACKETS_PRE, Constant.EMPTY).replace(Constant.SQUARE_BRACKETS_SUFFIX, Constant.EMPTY);
String[] newValuelist = newValue.split(Constant.COMMA);
for (int i = 0; i < newValuelist.length; i++) {
nvps.add(new BasicNameValuePair(name, newValuelist[i]));
}
} else {
nvps.add(new BasicNameValuePair(name, value));
}
}
httpPost.setEntity(new UrlEncodedFormEntity(nvps, apiRequestBody.getInputCharset()));
}
private static Map<String, Object> requestDataConvertToMap(ApiRequestBody apiRequestBody) {
Map<String, Object> params = new HashMap<>();
JSONObject formDataJson = (StringUtils.isNotEmpty(apiRequestBody.getRequestData())) ? JSONObject.parseObject(apiRequestBody.getRequestData()) : null;
if (formDataJson != null) {
//通过迭代器获取这段json当中所有的key值
Iterator keys = formDataJson.keySet().iterator();
//然后通过一个循环取出所有的key值
while (keys.hasNext()) {
String key = String.valueOf(keys.next());
String interfaceTemp = formDataJson.getString(key);
if (interfaceTemp == null) {
continue;
}
params.put(key, interfaceTemp);
}
}
return params;
}
private static void setConnectParams(ApiRequestBody apiRequestBody, HttpClient httpClient) {
httpClient.getParams().setParameter(AllClientPNames.CONNECTION_TIMEOUT, 30000);
httpClient.getParams().setParameter(AllClientPNames.SO_TIMEOUT, 30000);
httpClient.getParams().setParameter("http.protocol.content-charset", apiRequestBody.getInputCharset());
}