android系统定制开发跨域解决的三种方法、四种请求方式

同源:

同源:ajax请求的urlandroid系统定制开发和网页所在的urlandroid系统定制开发具有相同的协议,域名,ip和端口

同源策略:android系统定制开发为了数据安全,android系统定制开发浏览器禁止通过ajaxandroid系统定制开发请求读取非同源的数据(注意:android系统定制开发同源策略的两个关键点:1,浏览器 2,ajax请求)

同源策略下,浏览器会拦截跨域数据并报错,拦截的响应数据

跨域/跨源:ajax请求的url和网页所在的url具有不同的协议,域名,ip和端口

1,解决跨域请求报错的三种解决办法

1.1 COR头跨域

原理:在ajax请求的响应头中,添加cors字段,相当于令牌/通行证,可以避免浏览器拦截这个跨域数据(浏览器在接受ajax跨域数据时,会优先判断响应头中是否存在cors字段,如果有,则不拦截数据,如果没有,则报错)

步骤:在后端服务器接口响应之前,添加响应头

 // 在响应头中添加cors字段, 允许这个接口跨域访问 res.setHeader("Access-Control-Allow-Origin", "*")​//或​// 使用第三方cors模块允许跨域 (可一次设置所有接口跨域)var cors = require("cors")app.use(cors())

前端代码:

<h1 id="h1">这是主页</h1>    <script>        // 访问目标服务器的登录接口        $.get("http://localhost:5000/login?name=张三", function(data){            h1.innerText = data        })    </script>
  • 优点:简单方便,容易操作,前端请求无需修改ajax代码

  • 缺点:性降低,完全受后端限制,前端无法控制

1.2 jsonp跨域

原理:同源策略只对ajax请求有限制,非ajax请求无限制,非ajax请求(如:form表单请求、标签属性请求,a标签的href,img标签的src,script标签的src)不会被同源策略拦截,所以使用script标签的src属性发起的跨域请求不会被同源策略拦截。

步骤:前端(3种):

1,原生的jsonp请求:

前端:

 <script>        function myMethod(res){            console.log(res)            alert(res.name)        }    </script>    <script src="http://192.168.124.43:3000/userInfo?callback=myMethod"></script>
  • callback这个字段不能自定义,是jsonp内部规定好的字段,不用callback调用不了

后端:

app.get('/userInfo', function(req, res) {    console.log(req.query)    req.query.callback({ name: "李四" })})

2,常规的开发习惯写法

前端:

  <script>        function myMethod2(res){            alert(res.name)        }        $("<script>").attr("src", "http://192.168.124.43:3000/userInfo?callback=myMethod2").appendTo("body")    </script>

后端同1一样

3,jquery封装jsonp请求,使用$.getJSON()实现

前端:

 <script>        // 由于jquery封装后,回调函数是匿名函数, 所以参数写成  callback=?  ?代表后边匿名函数        $.getJSON("http://192.168.124.43:3000/userInfo?callback=?", function(res) {            alert(res.name)        })    </script>

后端:

app.get('/userInfo', function(req, res) {    console.log(req.query)     res.jsonp({ name: '李四' })})
  • jsonp()函数内部会自动调用get请求参数种的callback字段传入的回调函数,jsonp()参数作为callback回调函数的参数返回响应

  • jsonp函数的作用有两个:1,调用参数种的callback回调函数 2,返回响应数据

优点:不降低数据安全性,不完全受后端控制,相比于代理服务器跨域更简单

缺点:比cors头跨域复杂,受客户端和服务器共同控制,原理较复杂

1.3 代理服务器 跨域

原理:同源策略只对浏览器发起的ajax请求有限制,非浏览器请求无限制,所以可以使用网页所在的同源服务器发起ajax跨域请求,获取跨域数据后返回给同源客户端

步骤:创建同源服务器,在服务器种添加代理

前端:

 <h1 id="h1">这是主页</h1>    <script>        // 访问目标服务器的登录接口        $.get("/myApi/login?name=张三", function(data) {                h1.innerText += data            })            // 访问目标服务器的注册接口        $.post("/myApi/register?name=张三", function(data) {            h1.innerText += data        })    </script>

后端:

var proxy = require("http-proxy-middleware").createProxyMiddlewareapp.use("/myApi", proxy({    // 这个对象是代理的配置对象    target: "http://localhost:5000",   //目标服务器地址    changeOrigin: true,  // 修改请求路径    pathRewrite: {       // 路径修改方案        "^/myApi": ""    }}))​// http://localhost:3000/myApi/login?name=张三 // 以上请求url代理后的url如下// http://localhost:5000/login?name=张三​// http://localhost:3000/myApi/register?name=张三// 以上请求url代理后的url如下// http://localhost:5000/register?name=张三
  • 使用代理服务器跨域必须在前端服务器接口种下载并导入代理模块,并直接创建代理函数

  • 使用代理模块,调用代理函数,实现请求代理,这相当于创建了一个请求接口,同同源网页index.html访问,而参数"/myApi"就是同源请求的接口地址

2,四种方式

2.1 原生的ajax请求方式

get请求方式

var xhr = new XMLHttpRequest();        xhr.open("get", "http://open.douyucdn.cn/api/RoomApi/live?page=1")        xhr.send()        xhr.onreadystatechange = function() {            if (xhr.readyState == 4) {                console.log(1, JSON.parse(xhr.responseText))            }        }

post请求方式:

        var xhr = new XMLHttpRequest()        xhr.open("post", "http://open.douyucdn.cn/api/RoomApi/live")        xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded")        xhr.send("page=1")        xhr.onreadystatechange = function() {            if (xhr.readyState == 4) {                console.log(2, xhr.responseText);            }        }
  • 第一步:创建一个xhr对象 var xhr = new XMLHttpRequest();

  • 第二步:设置请求方式和请求URL xhr.open( ) 参数1为请求方式get/post,如果请求方式是get,则参数2的请求URL带传递参数;如果为post,则参数2的请求URL不带传递参数(即不带URL中的 ?后边的一系列参数)

  • 第三步:发送请求 xhr.send(); get请求,send不带参数;post请求,send参数是post请求的请求体, 也是键值对结构

  • 第四步:监听readystatechange ,判断readyState的请求准备状态是不是4;请求准备状态有1-4,1表示xhr创建;2表示数据处理完成;3表示请求已发送;4表示服务器返回结果,请求完成 responseText: "用户名已存在,注册失败"

2.2 jquery封装的ajax请求方式

 $.get("http://open.douyucdn.cn/api/RoomApi/live", {            page: 1        }, function(data) {            console.log(3.1, data);        })​ $.post("http://open.douyucdn.cn/api/RoomApi/live", {            page: 1        }, function(data) {            console.log(3.2, data);        })​ $.ajax({            type: "get",            url: "http://open.douyucdn.cn/api/RoomApi/live",            data: {                page: 1            },            success: function(data) {                console.log(3.3, data);            }        })

2.3 axios封装的ajax请求方式

使用axios前必须引入插件

    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>

get请求方式:

 axios.get("http://open.douyucdn.cn/api/RoomApi/live", {            params: {                page: 1            }        }).then(function(res) {            console.log(4.1, res.data);        })

post请求方式:

axios.post("http://open.douyucdn.cn/api/RoomApi/live", "page=1", {            headers: {                "Content-Type": "application/x-www-form-urlencoded"            }        }).then(function(res) {            console.log(4.2, res.data);        })
  • post请求数据没有在params字段中,get请求数据在params字段中

  • axios请求的回调函数在then函数中,而不是第三个参数

2.4 fetch函数请求

ES6中提供了一个函数fetch,是对原生ajax的封装,不需要插件,直接调用

fetch("http://open.douyucdn.cn/api/RoomApi/live?page=1").then(function(res) {  // res是响应信息对象,里边没有响应体数据,需要使用json函数解析后拿到响应体      console.log(4, res);      var obj = res.json(); //调用json函数解析数据,返回的是promise对象            console.log(5, obj);      obj.then(function(data) { //使用promise对象调用then函数拿到数据                console.log(data);            })                //实际开发直接写             res.json().then(function(data) {                console.log(6, data);            })     })
  • 响应数据也是通过then函数拿到,而回调函数的res是响应对象,没有响应体数据,需要解析之后才能拿到响应体数据,只能解析一次。解析之后是个promise对象直接调用then拿到data数据

报错:TypeError: Response.json: Body has already been consumed.(响应体已经被解析过了)

原因:res调用json()只能调用一次,也就是只能解析一次

网站建设定制开发 软件系统开发定制 定制软件开发 软件开发定制 定制app开发 app开发定制 app开发定制公司 电商商城定制开发 定制小程序开发 定制开发小程序 客户管理系统开发定制 定制网站 定制开发 crm开发定制 开发公司 小程序开发定制 定制软件 收款定制开发 企业网站定制开发 定制化开发 android系统定制开发 定制小程序开发费用 定制设计 专注app软件定制开发 软件开发定制定制 知名网站建设定制 软件定制开发供应商 应用系统定制开发 软件系统定制开发 企业管理系统定制开发 系统定制开发