1 错误场景

今天要把项目部署到外网的时候,出现了这种问题, 我把两个项目放到自己本机的tomcat下, 进行代码调试, 执行

都没有问题的, 一旦把我须要调用接口的项目B放到其它的server上, 就会报错, 无法通过Ajax调用springMVC的接口,

这是什么原因呢?

当我使用json ajax post请求传递数据的时候在web端出错:XMLHttpRequest cannot loadhttp://ip:8082/security/auth/outside.do.
Origin http://ip:8080 is not allowed by Access-Control-Allow-Origin.

2 初识jsonp

经过在网上查找, 网上大多数说是跨域问题. 解决跨域问题据说是jsonp, 百度了一篇文章, 无论三七二十一就一下

子把ajax传递的数据类型dataType 改成为jsonp, 并使用get方式, 单纯的觉得, json和jsonp没啥差别, 执行, 报错, 如

下图所看到的:

没有了上述的 is not allowed ....的错误, 变成了仅仅剩下500的错误, 说明jsonp起了些作用, 我的bug的问题就是在于网上说的"跨域" 。

而到底什么是跨域呢?

3 什么是跨域?什么是不跨域?           

上没有过多的去測试,一句话:同一个ip、同一个网络协议、同一个port。三者都满足就是同一个域,否则就是

跨域问题了。

而为什么开发人员最初不直接定为一切可跨域的呢?默认的为什么都是不可跨域呢?这就涉及到了同源策

略,为了系统的安全,由Netscape提出一个著名的安全策略。

如今全部支持JavaScript的浏览器都会使用这个策略。

所谓同源是,域名。协议,port同样。当我们在浏览器中打开百度和谷歌两个站点时,百度浏览器在运行一个脚本的

时候会检查这个脚本属于哪个页面的。即检查是否同源,仅仅有和百度同源的脚本才会被运行,假设没有同源策略,那

随便的向百度中注入一个js脚本,弹个恶意广告,通过js窃取信息。这就非常不安全了。

4 跨域问题怎样解决?jsonp为什么能解决跨域问题?和json有什么差别?

关于解决跨域问题,有多种解决方式,解决方式例如以下。

4.1 方案一

ajax请求地址改为自己系统的后台地址,之后在自己的后台用HttpClient请求url。封装好的跨域请求url工具类

代码例如以下所看到的。

<span style="font-size:18px;">@SuppressWarnings("all")
public final class UrlUtil { private static HttpClient httpClient = new HttpClient(); /**
* @Title: getDataFromURL
* @Description: 依据URL跨域获取输出结果。支持http
* @param strURL
* 要訪问的URL地址
* @param param
* 參数
* @return 结果字符串
* @throws Exception
*/
public static String getDataFromURL(String strURL, Map<String, String> param) throws Exception {
URL url = new URL(strURL);
URLConnection conn = url.openConnection();
conn.setDoOutput(true); OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream());
final StringBuilder sb = new StringBuilder(param.size() << 4); // 4次方
final Set<String> keys = param.keySet();
for (final String key : keys) {
final String value = param.get(key);
sb.append(key); // 不能包括特殊字符
sb.append('=');
sb.append(value);
sb.append('&');
}
// 将最后的 '&' 去掉
sb.deleteCharAt(sb.length() - 1);
writer.write(sb.toString());
writer.flush();
writer.close(); InputStreamReader reder = new InputStreamReader(conn.getInputStream(), "utf-8");
BufferedReader breader = new BufferedReader(reder);
// BufferedWriter w = new BufferedWriter(new FileWriter("d:/1.txt"));
String content = null;
String result = null;
while ((content = breader.readLine()) != null) {
result += content;
} return result;
} /**
* @Title: postMethod
* @Description: 依据URL跨域获取输出结果。支持https
* @param url
* 要訪问的URL地址(http://www.xxx.com?)
* @param urlParm
* 參数(id=1212&pwd=2332)
* @return 结果字符串
*/
public static String postMethod(String url, String urlParm) {
if (null == url || "".equals(url)) {
// url = "http://www.baidu.com";
return null;
}
PostMethod post = new PostMethod(url); // new UTF8PostMethod(url);
if (null != urlParm && !"".equals(urlParm)) {
String[] arr = urlParm.split("&");
NameValuePair[] data = new NameValuePair[arr.length];
for (int i = 0; i < arr.length; i++) {
String name = arr[i].substring(0, arr[i].lastIndexOf("="));
String value = arr[i].substring(arr[i].lastIndexOf("=") + 1);
data[i] = new NameValuePair(name, value);
}
post.setRequestBody(data);
}
int statusCode = 0;
String pageContent = "";
try {
statusCode = httpClient.executeMethod(post);
if (statusCode == HttpStatus.SC_OK || statusCode == HttpStatus.SC_MOVED_TEMPORARILY) {
pageContent = post.getResponseBodyAsString();
return pageContent;
}
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
post.releaseConnection();
}
return null;
} public static String doPost(String url, String json) throws Exception {
PostMethod postMethod = new PostMethod(url);
StringRequestEntity requestEntity = new StringRequestEntity(json, "application/json", "UTF-8");
postMethod.setRequestEntity(requestEntity);
/* 发送请求,并获取响应对象 */
int statusCode = httpClient.executeMethod(postMethod);
String result = null;
if (statusCode == HttpStatus.SC_OK) {
result = postMethod.getResponseBodyAsString();
} else {
System.out.println("Method failed: " + postMethod.getStatusLine());
}
return result;
} public static String post(String url, Map<String, String> params) {
DefaultHttpClient httpclient = new DefaultHttpClient();
String body = null;
HttpPost post = postForm(url, params);
body = invoke(httpclient, post);
httpclient.getConnectionManager().shutdown();
return body;
} private static HttpPost postForm(String url, Map<String, String> params) {
HttpPost httpost = new HttpPost(url);
List<BasicNameValuePair> nvps = new ArrayList<BasicNameValuePair>();
Set<String> keySet = params.keySet();
for (String key : keySet) {
BasicNameValuePair basicNameValuePair = new BasicNameValuePair(key, params.get(key));
nvps.add(basicNameValuePair);
}
try {
httpost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return httpost;
} private static String invoke(DefaultHttpClient httpclient, HttpUriRequest httpost) {
HttpResponse response = sendRequest(httpclient, httpost);
String body = paseResponse(response);
return body;
} private static HttpResponse sendRequest(DefaultHttpClient httpclient, HttpUriRequest httpost) {
HttpResponse response = null;
try {
response = httpclient.execute(httpost);
} catch (Exception e) {
e.printStackTrace();
}
return response;
} private static String paseResponse(HttpResponse response) {
HttpEntity entity = response.getEntity();
String body = null;
try {
body = EntityUtils.toString(entity);
} catch (Exception e) {
e.printStackTrace();
}
return body;
} public static void main(String[] args) throws Exception {
String url = "http://ip:8082/security/auth/outside.do";
Map<String, String> map = new HashMap<String, String>();
map.put("loginName", "root");
map.put("code", "vms2.0");
String msg = post(url, map);
JSONArray jary = JsonUtil.Json2JSONArray(msg);
for (int i = 0; i < jary.length(); i++) {
JSONObject obj = jary.getJSONObject(i);
System.out.println(obj);
// System.out.print(obj.getString("classid"));
// System.out.print("\t"+obj.getString("classname"));
// System.out.println("\t"+obj.getString("sonclass"));
}
// System.out.println(jary);
}
}</span>

当然要导入httpclient-4.3.1.jar包到自己的项目中哦。这样把请求的參数内容放到map中。通过HttpClent来实现跨域请求。

4.2 解决方式二

两个系统之间的数据传递是通过ajax post请求,传递json的方式来完毕,我们在这里能够使用jsonp的方式。但

是json和jsonp截然不同。首先说说神马是json,再说神马是jsonp。

json

全拼(javaScript Object Notation)轻量级的数据交换格式,易于机器解析和生成。基于javaScript

Programming Language,StandardECMA Edition December1999的一个子集。json全然独立于语言的文本格

式,可是也使用类似于C语言家族的习惯(include c c++ c# java javaScript perl python)等。这些特性使得json

成为理想的数据交换语言。格式为key,value格式,详细就不赘述了。

jsonp

jsonp全拼是(json with Padding)是json的一种使用模式,padding意思为填料,垫料,填充,填补。json可

以说是名词,而jsonp是动宾短语,两者有联系,可是有本质的差别,就像米饭和把米饭填充到碗里一样,那米饭和

米饭填是一样的么,我们自然明了了。

jsonp算是钻空子实现的跨域,究竟通过jsonp详细怎样解决跨域问题呢?本篇过长了,我们下篇分晓。goodnight...

跨域问题解决方式(HttpClient安全跨域 &amp; jsonp跨域)的更多相关文章

  1. 使用Httpclient来替代客户端的jsonp跨域解决方案

    最近接手一个项目,新项目需要调用老项目的接口,但是老项目和新项目不再同一个域名下,所以必须进行跨域调用了,但是老项目又不能进行任何修改,所以jsonp也无法解决了,于是想到了使用了Httpclient ...

  2. AJAX跨域问题解决方法(4)——调用方解决跨域

    调用方解决跨域的方法只有一种,那就是隐藏跨域. 何为隐藏跨域? 隐藏跨域的核心思路是通过反向代理隐藏跨域以欺骗浏览器 什么是反向代理?反向代理是指通过中间服务器使得访问同一个域名的两个不同url最终会 ...

  3. AJAX跨域问题解决方法(1)——禁止浏览器进行跨域限制

    思路:通过命令行修改浏览器启动参数,使得浏览器不进行跨域检查,从而允许跨域 方法:命令行参数启动浏览器后添加参数--disable-web-security 例:chrome --disable-we ...

  4. 深入剖析jsonp跨域原理

    在项目中遇到一个jsonp跨域的问题,于是仔细的研究了一番jsonp跨域的原理.搞明白了一些以前不是很懂的地方,比如: 1)jsonp跨域只能是get请求,而不能是post请求: 2)jsonp跨域的 ...

  5. 06: AJAX全套 & jsonp跨域AJAX

    目录: 1.1 AJAX介绍 1.2 jQuery AJAX(第一种) 1.3 原生ajax(第二种) 1.4 iframe“伪”AJAX(第三种) 1.5 jsonp跨域请求 1.6 在tornad ...

  6. jquery ajax怎么使用jsonp跨域访问

    在项目中使用接口的比较多,在客户端跨域访问,jquery中只能使用jquery ajax的jsonp方法. 值得注意的是,jQuery.ajax()只支持get方式的跨域,post的方式是不支持的.& ...

  7. 跨域问题解决方案(HttpClient安全跨域 & jsonp跨域)

    1 错误场景 今天要把项目部署到外网的时候,出现了这样的问题, 我把两个项目放到自己本机的tomcat下, 进行代码调试, 运行 都没有问题的, 一旦把我需要调用接口的项目B放到其他的服务器上, 就会 ...

  8. JavaScript跨域解决方式

    平时工作中经常被JavaScript跨域问题所困扰,其实有很多种解决方式,下面给大家介绍常用的几种: 1.jsonp解决跨域问题 客户端代码: <!DOCTYPE html> <ht ...

  9. 前端JavaScript实现跨域的方式(转)

    这里说的js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据.只要协议.域名.端口有任何一个不同,都被 ...

随机推荐

  1. [Cocos2dx Bug] [win32] Function CCFileUtils::fullPathFromRelativeFile forget consider the path separated by '\\'

    [Cocos2dx 2.2.4] [win32平台Bug] const char* CCFileUtils::fullPathFromRelativeFile(const char *pszFilen ...

  2. 多线程(继承Thread)

    /** *Thread的常用方法 *1.start(),启动线程再执行run方法 *2.run():子线程要执行的代码放入run()方法中 *3.currentThread()静态的,调取当前线程,返 ...

  3. PHP网站提交表单如何实现验证码验证功能

    很多小伙伴在原生网站时候都会遇到很多意料之外的情况发生,也有不少小伙伴在初学程序代码的时候可能会因为一个小小的逗号隐藏在几百行,几千行的代码中出错常见的在提交表单中很多事需要验证码验证,那么如何来实现 ...

  4. 【HDU 1686 Oulipo】

    Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission( ...

  5. linux之stat

    stat指令:文件/文件系统的详细信息显示: 使用格式:stat 文件名 stat命令主要用于显示文件或文件系统的详细信息,该命令的语法格式如下: -f 不显示文件本身的信息,显示文件所在文件系统的信 ...

  6. BZOJ 2728: [HNOI2012]与非

    2728: [HNOI2012]与非 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 786  Solved: 371[Submit][Status][ ...

  7. *UOJ#223. 【NOI2016】国王饮水记

    $n \leq 8000$的数列,问不超过$m \leq 1e9$次操作后第一个数字最大是多少.操作:选一些数,把他们变成他们的平均值.需要保留$p \leq 3000$位小数,提供了一个小数高精度库 ...

  8. 图片上传封装类【包括图片上传和缩略图上传】.NET

    原文发布时间为:2009-08-30 -- 来源于本人的百度文章 [由搬家工具导入] #region 上传图片及上传缩略图    public class UpFile : System.Web.UI ...

  9. Method, apparatus, and system for speculative abort control mechanisms

    An apparatus and method is described herein for providing robust speculative code section abort cont ...

  10. javascript 动态添加城市

    匿名函数的使用 createTextnode 创建文本 createElement   创建元素 appendChild     将文本或元素追加 <!DOCTYPE html> < ...