AJAX 跨域解决方案

AJAX 跨域解决方案,第1张

# 前后端分离( 服务器)

- 前端资源(html)- server-a 提供前端静态资源

- 后端数据(商品信息……)- server-b 提供基于http的api

#同源策略

当我们通过 xhr 的方式从一个源去获取另外一个源的数据的时候,就会触发同源策略的协议

**源**

域:协议+主机(ip、域名)+端口,比如 http://localhost:8888

**同源策略**

**浏览器**的安全设定,避免浏览器中通过脚本等方式去获取非同源的数据

官方文档:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CORS

这套机制建立在一个核心内容基础之上:**http header**,这套机制定义了一系列的http头,通过这些http头来控制资源的访问。这些http头基本都是以 `access-control-?` 来进行命名的,不同的http头有不同的作用。

#普通资源请求

**[Access-Control-Allow-Origin](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CORS#access-control-allow-origin)**

控制当前允许访问该资源的源(origin)

# 非普通的资源请求

**简单请求 &非简单请求**

当请求满足一定规则的时候,为简单请求

https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CORS#%E7%AE%80%E5%8D%95%E8%AF%B7%E6%B1%82

**预检请求**

如果当前请求满足了非简单请求,那么就会先发送一个 method 为 options 的请求(浏览器),称为**预检**,后端需要对这个预检请求进行处理,根据业务返回对应的头信息,来告知客户端是否允许发送非简单请求,我们需要在预检请求中返回一系列的头信息,来控制之前发送的非简单请求是否继续

https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CORS#%E9%A2%84%E6%A3%80%E8%AF%B7%E6%B1%82

**附带身份凭证的请求**

cookie 实际也是会受到同源策略的限制的,如果非同源请求,cookie是默认被禁止携带处理的。

解决:

- 客户端在请求中要设置:withCredentials: true

- 服务端要在cors中设置:ctx.set('Access-Control-Allow-Credentials', 'true')

## 利用 koa-server-http-proxy 实现服务端代理

利用 koa-server-http-proxy 来处理正向代理

## 基于jwt鉴权(jsonwebtoken)

**cookie**

使用cookie来实现用户鉴权

- 目前cookie限制太多

- cookie会在一些情况下被禁用

**放置另外一个地方**

- 请求必须是可控的(ajax)

- 基于前后端开发的应用基本都是使用ajax方式进行

**jwt**

https://jwt.io/introduction

解决的办法,有如下几种:

1. 使用中间层过渡的方式(可以理解为“代理”):

中间过渡,很明显,就是在AJAX与不同域的服务器进行通讯的中间加一层过渡,这一层过渡可以是PHP、JSP、c++等任何具备网络通讯功能的语言,由中间层向不同域的服务器进行读取数据的 *** 作。拿asp.net做一个例子,如果需要对不同域的某一个asp.net进行通讯,现在客户端的xmlhttprequest先query本域的一个asp.net ,然后由本域的这个asp.net去和不同域的asp.net进行通讯,然后由本域的asp.net响应输出(response)

2. 使用<script>标签

这个方法是利用<script>标签中的src来query一个aspx获得response,因为<script>标签的src属性不存在跨域的问题。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

    <title>Ajax跨域问题</title>

    <script type="text/javascript" src="" id="getAspx">

    </script>

    <script type="text/javascript">

        function get(url) {

            var obj = document.getElementById("getAspx")

            obj.src = url

            (obj.readStatus == 200)

            {

                alert(responseVal)//如果成功,会d出Dylan

            }

        }

        function query() {

            get(getDemo.aspx)

        }

    </script>

</head>

<body>

<input type="button" value="Ajax跨域测试" onclick="query()"/>

</body>

</html>

getDemo.aspx后台代码:

using System

using System.Collections.Generic

using System.Linq

using System.Web

using System.Web.UI

using System.Web.UI.WebControls

namespace LearnJS

{

    public partial class getDemo : System.Web.UI.Page

    {

        protected void Page_Load(object sender, EventArgs e)

        {

            Response.Write("var responseVal='Dylan'")

        }

    }

}

这个方法又叫做ajaj或者ajax without xmlHttprequest,把x换成了j,是因为使用了<script>标签而没有用到xml和xmlHttprequest的缘故。

有了jQuery之后,如何来解决ajax的跨域问题:

<html>

<head>

<title>JQuery学习</title>

<script src="jquery-1.4.2.min.js" type="text/javascript"></script>

<script type="text/javascript">

$(document).ready(function(){

    var oBtnTest = $("#btnTest")

    oBtnTest.click(function(){

        oBtnTest.disabled = true    

        var oResult = $("#result")

        oResult.html("loading").css("color","red")

        jQuery.getScript("http://www.jb51.net/test/js.txt", 

        function(){            

            oResult.html("name:" + Dylan.name + "<br/>email:" + Dylan.email).css("color","black")            

            oBtnTest.disabled = false            

        })         

    })    

})    

</script>

</head>

<body>

<button id="btnTest">BtnTest</button>

<div id="result"></div>

</body>

</html>

远程服务器端js.txt中的内容为:

var Dylan= {name:"Dylan",email:Dylan@163.com}


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/6157842.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-03-16
下一篇 2023-03-16

发表评论

登录后才能评论

评论列表(0条)

保存