1 错误场景

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

都没有问题的, 一旦把我需要调用接口的项目B放到其他的服务器上, 就会报错, 无法通过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、同一个网络协议、同一个端口,三者都满足就是同一个域,否则就是

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

略,为了系统的安全,由Netscape提出一个著名的安全策略。现在所有支持JavaScript的浏览器都会使用这个策略。

所谓同源是,域名,协议,端口相同。当我们在浏览器中打开百度和谷歌两个网站时,百度浏览器在执行一个脚本的

时候会检查这个脚本属于哪个页面的,即检查是否同源,只有和百度同源的脚本才会被执行,如果没有同源策略,那

随便的向百度中注入一个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);
    }
}

当然要导入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# JavajavaScript perl Python)等,这些特性使得json

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

jsonp

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

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

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

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

  1. JSONP跨域的script标签请求为什么不受同源策略的限制?

    在复习跨域的时候,复习到了JSONP跨域,大家都知道JSONP跨域是通过动态创建script标签,然后通过其src属性进行跨域请求的,前端需要一个数据处理的回调函数,而服务端需要配合执行回调函数,放入 ...

  2. C#进阶系列——WebApi 跨域问题解决方案:CORS

    前言:上篇总结了下WebApi的接口测试工具的使用,这篇接着来看看WebAPI的另一个常见问题:跨域问题.本篇主要从实例的角度分享下CORS解决跨域问题一些细节. WebApi系列文章 C#进阶系列— ...

  3. 跨域解决方案一:使用CORS实现跨域

    跨站HTTP请求(Cross-site HTTP request)是指发起请求的资源所在域不同于请求指向的资源所在域的HTTP请求. 比如说,我在Web网站A(www.a.com)中通过<img ...

  4. thinkphp,javascript跨域请求解决方案

    javascript跨域请求解决方案 前言 对于很多前端或者做混合开发的同学,我们难免会遇到跨域发起请求业务,比如A站点向B站点请求数据等等.由于最近要做一个站点集群的项目,所以具体业务要求很多个站点 ...

  5. jquery跨域访问解决方案(转)

    客户端“跨域访问”一直是一个头疼的问题,好在有jQuery帮忙,从jQuery-1.2以后跨域问题便迎刃而解.由于自己在项目中遇到跨域问题,借此机会对跨域问题来刨根问底,查阅了相关资料和自己的实践,算 ...

  6. ajax跨域请求解决方案

    大家好,今天我们学习了js的跨域请求的解决方案,由于JS中存在同源策略,当请求不同协议名,不同端口号.不同主机名下面的文件时,将会违背同源策略,无法请求成功!需要进行跨域处理! 方案一.后台PHP进行 ...

  7. C#进阶系列——WebApi 跨域问题解决方案:CORS(转载)

    C#进阶系列——WebApi 跨域问题解决方案:CORS   阅读目录 一.跨域问题的由来 二.跨域问题解决原理 三.跨域问题解决细节 1.场景描述 2.场景测试 四.总结 正文 前言:上篇总结了下W ...

  8. 跨域学习笔记2--WebApi 跨域问题解决方案:CORS

    自己并不懂,在此先记录下来,留待以后学习... 正文 前言:上篇总结了下WebApi的接口测试工具的使用,这篇接着来看看WebAPI的另一个常见问题:跨域问题.本篇主要从实例的角度分享下CORS解决跨 ...

  9. Ajax跨域访问解决方案

    No 'Access-Control-Allow-Origin' header is present on the requested resource. 当使用ajax访问远程服务器时,请求失败,浏 ...

随机推荐

  1. 【树莓派】制作树莓派最小镜像:img裁剪瘦身

    制作树莓派镜像,可以参考这篇文章:http://blog.csdn.net/talkxin/article/details/50456282 摘录部分要点内容如下(如果作者不允许转载,请联系即删除): ...

  2. python计算文件夹大小(linux du命令 简化版)

    C盘又满了,怎么办?用了一些垃圾清理软件(或者bat脚本),但是还是不理想,那么具体哪些文件夹下面有巨大的文件呢?windows并不能通过详细信息看到每个文件夹的大小(PS:这里所谓的文件夹的大小是指 ...

  3. JAVA-Servlet-ServletConfig 与 ServletContext 的区别

    什么是ServletConfig? Servlet容器初始化一个servlet对象时,会为这个servlet对象创建一个servletConfig对象.在servletConfig对象中包含了serv ...

  4. 关于npm安装全局模块,require时报Error: Cannot find module 'XXX'的解决办法

    系统环境:centos 下午使用npm安装"cheerio",想搞爬虫玩玩. npm安装有两种模式: 本地 # npm install cheerio 全局 # npm insta ...

  5. 配置linux实现路由功能

    说明: 主机1是内网的数据存储服务器,只有一块网卡10.0.0.2: 主机2是web服务器,有两块网卡,一块面向内网10.0.0.3,一块面向外网192.168.220.136: (因为是在虚拟机的环 ...

  6. CCNA网络工程师学习进程(10)NAT的配置

     NAT(Network Address Translation,网络地址转换)是将IP 数据包头中的IP 地址转换为另一个IP 地址的过程.     (1)NAT简介:     在实际应用中,NAT ...

  7. MYSQL数据库-其他

    FROM:实验楼 索引: 当表中有大量记录时,若要对表进行查询,没有索引的情况是全表搜索.而如果在表中已建立索引,在索引中找到符合查询条件的索引值,通过索引值就可以快速找到表中的数据. 建立索引: $ ...

  8. [编织消息框架][JAVA核心技术]jdk动态代理

    需要用到的工具  jdk : javac javap class 反编译 :JD-GUI http://jd.benow.ca/ import java.lang.reflect.Invocation ...

  9. STM32GPIO口8种模式细致分析(类比51单片机)

    关于STM32GPIO口的8种工作模式,我们先引出一些问题? STM32GPIO口如果既要输入又要输出怎么办? 1.浮空输入模式 上图红色的表示便是浮空输入的过程,外部输入时0读出的就是0,外部输入时 ...

  10. HTML5 WebSocket和后端C#通信

    1.使用 HTML5 开发离线应用 http://www.ibm.com/developerworks/cn/web/1011_guozb_html5off/ 2.利用html 5 websocket ...