zoukankan      html  css  js  c++  java
  • XmlHttpRequest使用及“跨域”问题解决

    一. IE7以后对xmlHttpRequest 对象的创建在不同浏览器上是兼容的。

         下面的方法是考虑兼容性的,实际项目中一般使用Jquery的ajax请求,可以不考虑兼容性问题

    function getHttpObject() {
    var xhr=false;
    if (windows.XMLHttpRequest)
        xhr=new XMLHttpRequest();
    else if (window.ActiveXObject)
    {
        xhr=new ActiveXObject("Microsoft.XMLHttp");
    }
    return xhr;
    }
     

     

     

    二. XMLHttpRequest的属性及方法

    1、方法 描述
    abort() 停止当前请求
    getAllResponseHeaders() 把HTTP请求的所有响应首部作为键/值对返回
    getResponseHeader(“header”) 返回指定键的首部串值
    open(“method”,”url”) 建立对服务器的调用,Method可以是GET,POST或PUT,URL可以是相对或绝对URL
    send(content) 向服务器发送请求
    setRequestHeader(“header”,”value”) 把指定首部设置为所提供的值。在设置任何首部之前必须调用open()


    2、属性 描述
    onreadystatechange 每个状态改变都会触发,通常会调用一个javascript函数
    readyState 请求的状态,5个值; 0:为初始化,1:正在加载;2:已经加载,3:交互中,4:完成
    responseText 服务器的响应,表示为字符串
    responseXML 服务器的响应,表示为XML,可以解析为DOM对象
    status 服务器的HTTP状态码(200:ok,304:not modified,404:Not Found 等)
    statusText Http状态码的相应文本(ok或Not Found)

     

    3、手写一个Ajax请求的例子:

      eg1: get
    $(function(){
          $("#id").onclick(tunction(){
              var request=new XMLHttpRequest();
              var url="http://www.baidu.com";
              var method="GET";    
              request.open(method,url);
              request.send(null);
              request.onreadystatechange=function(){
                 if (request.readyState==4&&(request.status==200 || request.status==304))
                    alert (request.reponseText);
                    //如果返回的是html 标签,则可以使用 
              //$(“#id2”).innerHtml=request.reponseText;
                    //如果返回的xml格式,则需要将结果通过getElementByTagName(“”)[index]解析
             //alert(request.reponseXML.getElementByTagName(“”)[index])
     
              /*var type=request.getResponseHeader("Content-Type");
                    if(type.indexOf("xml") !== -1 && request.responseXML){ 
                        callback(request.responseXML); //Document对象响应
                    }else if(type=== 'application/json'){
                        callback(JSON.parse(request.responseText)) //JSON响应
                    }else {
                        callback(request.responseText);
                    }*/
    } }) })
     
      eg2: post
    <script type="text/javascript">
        var xhr = new XMLHttpRequest();
        xhr.timeout = 3000;
        xhr.ontimeout = function (event) {
            alert("请求超时!");
        }
        var formData = new FormData();
        formData.append('tel', '18217767969');
        formData.append('psw', '111111');
        xhr.open('POST', 'http://www.test.com:8000/login');
        xhr.send(formData);
        xhr.onreadystatechange = function () {
            if (xhr.readyState == 4 && xhr.status == 200) {
                alert(xhr.responseText);
            }
            else {
                alert(xhr.statusText);
            }
        }
    </script>

    eg3:同步响应
        //同步响应
        //发起同步的HTTP GET请求以获得指定URL的内容
        //返回响应文本,或如果请求不成功或响应不是文本就报错。
        function getTextSync(url){
            var request=new XMLHttpRequest();
            request.open("GET",url,false); //把fasle作为第三个参数传递给open(),那么send()方法将阻塞直到请求完成
            request.send(null);
    
            if(request.status!==200) throw new Error(request.statusText);
    
            var type=request.getResponseHeader('Content-Type');
            if(!type.match(/^text/)) throw new Error("Expected textual respomse;got:"+type);
    
            return request.responseText;
        }

     

    三、.跨域资源共享(CORS)

    XMLHttpRequest可以向不同域名的服务器发出HTTP请求,叫做CORS

    解决方案:

    1)、服务器允许跨域:响应头需要添加一下选项

         CORS头缺少“Access-Control-Allow-Origin”, 这个错误代表: 服务端拒绝跨域访问。如果出现这个错误,就需要在服务端设置允许跨域请求

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
    
        // * 表示允许任何域名跨域访问
        response.setHeader("Access-Control-Allow-Origin", "*");
        // 指定特定域名可以访问
        response.setHeader("Access-Control-Allow-Origin", "http:localhost:8080/");
    
        //数据
        List<Student> studentList = getStudentList();
    
        JSONArray jsonArray = JSONArray.fromObject(studentList);
        String result = jsonArray.toString();
    
        //前端传过来的回调函数名称
        String callback = request.getParameter("callback");
        //用回调函数名称包裹返回数据,这样,返回数据就作为回调函数的参数传回去了
        result = callback + "(" + result + ")";
    
        response.getWriter().write(result);
    }
    

      

    2)、JSONP,jsonp有缺点,只能发送get请求

    下面的方法是考虑兼容性的,实际项目中一般使用Jquery的ajax请求,可以不考虑兼容性问题。

    eg1:如何使用<script src="">来完成一个跨域请求
    前台:

    <%@ page pageEncoding="utf-8" contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
    <title>跨域测试</title>
    <script src="js/jquery-1.7.2.js"></script>
    <script>
    //回调函数
    function showData (result) {
    var data = JSON.stringify(result); //json对象转成字符串
    $("#text").val(data);
    }

    $(document).ready(function () {

    $("#btn").click(function () {
    //向头部输入一个脚本,该脚本发起一个跨域请求
    $("head").append("<script src='http://localhost:9090/student?callback=showData'></script>");
    });

    });
    </script>
    </head>
    <body>
    <input id="btn" type="button" value="跨域获取数据" />
    <textarea id="text" style=" 400px; height: 100px;"></textarea>

    </body>
    </html>

     
    后台:

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    response.setCharacterEncoding("UTF-8");
    response.setContentType("text/html;charset=UTF-8");

    //数据
    List<Student> studentList = getStudentList();


    JSONArray jsonArray = JSONArray.fromObject(studentList);
    String result = jsonArray.toString();

    //前端传过来的回调函数名称
    String callback = request.getParameter("callback");
    //用回调函数名称包裹返回数据,这样,返回数据就作为回调函数的参数传回去了
    result = callback + "(" + result + ")";

    response.getWriter().write(result);
    }

    eg2:jquery的jsonp方式跨域请求

    ---后台代码还是上面的

    <%@ page pageEncoding="utf-8" contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
    <title>跨域测试</title>
    <script src="js/jquery-1.7.2.js"></script>
    <script>

    $(document).ready(function () {

    $("#btn").click(function () {

    $.ajax({
    url: "http://localhost:9090/student",
    type: "GET",
    dataType: "jsonp", //指定服务器返回的数据类型
    success: function (data) {
    var result = JSON.stringify(data); //json对象转成字符串
    $("#text").val(result);
    }
    });

    });

    });
    </script>
    </head>
    <body>
    <input id="btn" type="button" value="跨域获取数据" />
    <textarea id="text" style=" 400px; height: 100px;"></textarea>

    </body>
    </html>

     3)、搭建网关系统

     

    附其他:

    这里再插入一下window.onload 和$(function(){})($(document).ready(function(){}))的区别:

    1. window.onload 必须等到页面内包括图片的所有元素加载完毕才能执行

        $(function(){}) 是DOM结构绘制完毕后就执行,不必等到加载完毕

    2. 编写个数不同

        window.onload 不能同时编写多个,如果有多个window.onload方法,只会执行一个

        $(function(){}) 可以同时编写多个,并且都会得到执行

    3. 简化写法

        window.onload 没有简写方法,但可以使用$(window).load(function(){})代替

        $(function(){})实际是$(document).ready(function(){})的缩写方法

        $(window).load(function(){}),IE只有在不是frame的情况下,一般情况下都会在$(function(){})之后执行.

     

  • 相关阅读:
    MySql 免安装配置
    MySql 语句优化的几个小建议
    Sharding-JDBC 公共表
    Sharding-JDBC 垂直分库
    Sharding-JDBC 水平分库
    Vuejs基础使用
    webpack配置开发环境和生产环境
    webpack常见应用
    webpack-用loader加载css样式、图片、字体、数据
    webpack核心概念-模式/loader/插件及其他
  • 原文地址:https://www.cnblogs.com/651434092qq/p/11109199.html
Copyright © 2011-2022 走看看