js 跨域访问问题解决方法

news2024/11/28 10:55:08

什么引起了ajax不能跨域请求的问题?

ajax本身实际上是通过XMLHttpRequest对象来进行数据的交互,而浏览器出于安全考虑,不允许js代码进行跨域操作,所以会警告。

 

有什么完美的解决方案么?

解决方案有不少,但是只能是根据自己的实际情况来选择。

 

跨域的安全限制都是指浏览器端来说的,服务器端是不存在跨域安全限制的。所以针对这2种情况衍生出2类跨域解决方案,一类是服务器端做中转类似代理方式,一类是js处理浏览器端的真正跨域访问。

 

具体情况有:

  1.   本域和子域的相互访问: www.aa.com和book.aa.com 用document.domain = "aa.com";
  2. 本域和其他域的相互访问: www.aa.com和www.bb.com 用 XMLHttpRequest访问代理,既服务器端代理方式
  3. 本域和其他域的相互访问: www.aa.com和www.bb.com 用 JS创建动态脚本,<script>标签的src属性实现跨域访问

 

解决方法:

 

  1. 如果想做到数据的交互,那么www.aa.com和book.aa.com必须由你来开发才可以。可以将book.aa.com用iframe添加到 www.aa.com的某个页面下,在www.aa.com和iframe里面都加上document.domain = "aa.com",这样就可以统一域了,可以实现跨域访问。就和平时同一个域中镶嵌iframe一样,直接调用里面的JS就可以了。
  2. 这种情形是最经常遇到的,也是用的最多的了。就是www.aa.com和www.bb.com你只能修改一个,也就是另外一个是别人的,人家告诉你你要取得数据就访问某某连接参数是什么样子的,最后返回数据是什么格式的。而你需要做的就是让你的服务器端充当中转代理,让服务器去别人的网站上取得数据,再返回给浏览器端。

服务器端充当中转代理方式有很多可以由服务器端程序实现,也可以修改服务器配置实现,下面举例Apache重写(mod_rewrite proxy模式)方式:
在Apache的安装目录下的conf/httpd.conf 文件添加如下语句:

LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule rewrite_module modules/mod_rewrite.so
RewriteEngine On
RewriteRule ^/_proxy/(.*)$ http://$1 [P,L]


这样就可以把其他网站的url映射为本服务器的/_proxy/目录下面, 例如可以这么访问百度http://html.duqn.com/_proxy/www.baidu.com


 这个的区别就是请求是使用<script>标签来请求的,这个要求也是两个域都是由你来开发才行。原理就是JS文件注入,在本域内的aa.com 内生成一个JS标签,它的SRC指向请求的另外一个域bb.com的某个页面b,b返回数据即可,可以直接返回JS的代码。因为script的src属性是可以跨域的。具体看代码,这个也比较简单。

aa.com/a.jsp

<script type="text/javascript">
function myTest(data) {
    alert(data);
}
</script>
<script type="text/javascript" src="http://www.bb.com/index!getData.action?jsoncallback=myTest"></script>
 

 

bb.com/b.jsp页面代码如下:

 

$(param.jsoncallback)({"name": "Zhang Huihua", "QQ": "350863780"})

b.jsp页面通过$(param.jsoncallback)得到浏览器端随后要回调的js function name:myTest

实际上客户端接收到的response如下:myTest({"name": "Zhang Huihua", "QQ": "350863780"})

 

 

 

jQuery浏览器端跨域访问

目前jQuery $.ajax()支持get方式的跨域,这其实是采用jsonp的方式来完成的。其原理就是上面第三种方式,<script>标签的src属性实现跨域访问

真实案例代码如下:

$.ajax({
    url: http://跨域的dns/index!searchJSONResult.action,
    type: "GET",
    dataType: 'jsonp',
    data: {name:”ZhangHuihua”},
    timeout: 5000,
    success: function (json) {//客户端jquery预先定义好的callback函数,成功获取跨域服务器上的json数据后,会动态执行这个callback函数
        alert(json);
    },
    error: function (xhr, ajaxOptions, thrownError){
          alert("Http status: " + xhr.status + " " + xhr.statusText + "\najaxOptions: " + ajaxOptions + "\nthrownError:"+thrownError + "\n" +xhr.responseText);
    }
 
});

注意:

$.getJSON("http://跨域的dns/index!searchJSONResult.action?name1="+value1+"&jsonCallback=?", function(json){
    // 执行代码
});

这种方式其实是上例$.ajax({..}) api的一种高级封装,有些$.ajax api底层的参数就被封装而不可见了.

这样,jquery就会拼装成如下的url get请求

http:// 跨域的 dns/index!searchJSONResult.action?&jsonCallback=jsonp1236827957501&_=1236828192549&name=ZhangHuihua

 

jsonCallback自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名,也可以写"?",jQuery会自动为你处理数据.

 

在响应端(http://跨域的dns/index!searchJSONResult.action),

通过 jsoncallback = request.getParameter("jsoncallback") 得到jquery端随后要回调的js function name:jsonp1236827957501

然后 response的内容为一个Script Tags:"jsonp1236827957501("+按请求参数生成的json数组+")";

jquery就会通过回调方法动态加载调用这个js tag:jsonp1236827957501(json数组);

这样就达到了跨域数据交换的目的.

 

jsonp的最基本的原理是:动态添加一个<script>标签,而script标签的src属性是没有跨域的限制的。这样说来,这种跨域方式其实与ajax XmlHttpRequest协议无关了.

这样其实"jQuery AJAX跨域问题"就成了个伪命题了,jquery $.ajax方法名有误导人之嫌.

如果设为dataType: 'jsonp', 这个$.ajax方法就和ajax XmlHttpRequest没什么关系了,取而代之的则是JSONP协议.

JSONP是一个非官方的协议,它允许在服务器端集成Script tags返回至客户端,通过javascript callback的形式实现跨域访问

JSONP即JSON with Padding。由于同源策略的限制,XmlHttpRequest只允许请求当前源(域名、协议、端口)的资源。如果要进行跨域请求,

我们可以通过使用html的script标记来进行跨域请求,并在响应中返回要执行的script代码,其中可以直接使用JSON传递javascript对象。

这种跨域的通讯方式称为JSONP。

jsonCallback 函数jsonp1236827957501(....): 是浏览器客户端注册的,获取跨域服务器上的json数据后,回调的函数

 

Jsonp原理:

首先在客户端注册一个callback (如:'jsoncallback'), 然后把callback的名字(如:jsonp1236827957501)传给服务器。

此时,服务器先生成 json 数据。

然后以 javascript 语法的方式,生成一个function , function 名字就是传递上来的参数 'jsoncallback'的值 jsonp1236827957501 .

最后将 json 数据直接以入参的方式,放置到 function 中,这样就生成了一段 js 语法的文档,返回给客户端。

客户端浏览器,解析script标签,并执行返回的 javascript 文档,此时javascript文档数据,作为参数,

传入到了客户端预先定义好的 callback 函数(如上例中jquery $.ajax()方法封装的的success: function (json))里.(动态执行回调函数)

可以说jsonp的方式原理上和<script src="http://跨域/...xx.js"></script>是一致的(qq空间就是大量采用这种方式来实现跨域数据交换的) .JSONP是一种脚本注入(Script Injection)行为,所以也有一定的安全隐患.

 

注意,jquey是不支持post方式跨域的.

虽然采用post +动态生成iframe是可以达到post跨域的目的,但这样做是一个比较极端的方式,不建议采用.

也可以说get方式的跨域是合法的,post方式从安全角度上,被认为是不合法的, 万不得已还是不要剑走偏锋..

浏览器端跨域访问的需求看来也引起w3c的注意了,看资料说html5 WebSocket标准支持跨域的数据交换,应该也是一个将来可选的跨域数据交换的解决方案.

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/142818.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数字化门店管理|如何让门店数字化管理,更加贴合日常运营细节?

在赋能品牌门店数字化管理的过程中&#xff0c;帷幄既注重前沿 AI 算法带来的技术驱动力&#xff0c;也注重基于门店管理中的真实场景与需求&#xff0c;让算法更贴合业务实际需求&#xff0c;从而带来运营优化与降本增效。 1 月&#xff0c;「帷幄数智空间 Whale SpaceSight」…

植物大战 动态内存——C++

这里是目录标题前言动态内存分布如何理解C语法的增加newnew用法关于struct和class的使用关于free和delete的区别。背会这句话抛异常operator new和operator delete内存池new和delete原理定位newmalloc和new的区别是什么&#xff1f;内存泄漏前言 总结复习前面的知识。 注意&a…

一文带你了解什么是云计算网络运维工程师,以及2023年的就业前景

作者简介&#xff1a;一名在校云计算网络运维学生、每天分享网络运维的学习经验、和学习笔记。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​​ 目录 前言 一.云计算网络运维工程师是做什么的? 二.作为一名云计算网络运…

MyBatis(用于简化JDBC开发)

MyBatis是一款持久层框架&#xff0c;用于简化JDBC开发 持久层&#xff1a;将数据报错到数据库&#xff0c;持久化更改的意思 javaEE三层架构&#xff1a;表现层&#xff08;页面&#xff09;、业务层&#xff08;处理逻辑&#xff09;、持久层&#xff08;数据永久化更改&am…

拉伯证券|人心动了?刚刚,A股、港股大涨!

昨日A股传言较多&#xff0c;引发波动。上一年10月底11月初&#xff0c;也有类似情况。换个视点看&#xff0c;这说明人心开端动了&#xff0c;至于怎样个“思变”法&#xff0c;市场可能现已给出了答案&#xff01; 今天上午&#xff0c;A股大涨&#xff0c;北向资金净流入110…

cs231n-2022-01 Assignments1-numpy的使用

numpy的使用 Numpy是Python中科学计算的核心库。它提供了一个高性能的多维数组对象&#xff0c;以及处理这些数组的工具。如果你已经熟悉MATLAB&#xff0c;你可能会发现这个教程对开始使用Numpy很有用。 运行并阅读cs231n课程网站上提供的示例代码&#xff0c;感觉十分简洁&a…

TIA博途SCL学习_堆栈的入栈和出栈(后入先出)程序示例

TIA博途SCL学习_堆栈的入栈和出栈(后入先出)程序示例 如下图所示,添加一个FB块,语言选择SCL,命名为“入栈”, 如下图所示,通过FOR循环实现堆栈数组内的元素的移动,并将入栈的数据赋值给数组的第一个元素, 如下图所示,添加一个全局DB块,在该DB块中添加一个长度为10…

Visio中插入Mathtyp公式

Visio中插入Mathtype公式 打开visio软件&#xff0c;依次点击“插入”–“对象”–“mathtype 6.0 equation”–“确定”&#xff0c;也可以得到我们想要的公式。 点击“对象”&#xff0c;然后显示出Mathtype公式 点击“Mathtype 7.0”&#xff0c;然后显示公式框 Way 1&a…

win10和win11鼠标灵敏度修改和大小颜色其他等步骤

目录 一、前言 二、win10鼠标设置 1.进入鼠标设置界面 2.鼠标速度的调节 3.鼠标大小和颜色的调节 4.鼠标其他设置 三、win11鼠标设置 1.进入搜索界面 2.鼠标大小和颜色设置 3.鼠标的移动灵敏速度设置 4.鼠标图标的自定义 一、前言 在使用电脑鼠标时候&#xff0c;会觉…

【自然语言处理】【ChatGPT系列】WebGPT:基于人类反馈的浏览器辅助问答

WebGPT: 基于人类反馈的浏览器辅助问答《WebGPT: Browser-assisted question-answering with human feedback》论文地址&#xff1a;https://arxiv.org/pdf/2112.09332.pdf 相关博客 【自然语言处理】【ChatGPT系列】WebGPT&#xff1a;基于人类反馈的浏览器辅助问答 【自然语言…

[HTML] HTML基础知识

1.HTML简介 HTML指的是超文本标记语言(HyperText Markup Language)&#xff0c;是一种用于创建网页的标准标记语言 HTML页面基本结构 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X…

SpringMVC框架

一、什么是 SpringMVC ? SpringMVC框架是以请求为驱动&#xff0c;围绕Servlet设计&#xff0c;将请求发给控制器&#xff0c;然后通过模型对象&#xff0c;分派器来展示请求结果视图。其中核心类是DispatcherServlet&#xff0c;它是一个Servlet&#xff0c;顶层是实现的Ser…

不会指针?还不进来看看——进阶指针详解

专栏&#xff1a;C语言 每日一句&#xff1a;人贵有自知之明&#xff0c;知道什么可为和不可为。若不可为&#xff0c;怎样做才能可为&#xff0c;那何时可为。 进阶指针前言一、字符指针二、指针数组1.指针数组的介绍2.指针数组的使用三、数组指针1.数组指针的介绍2.&数组…

历史大讲堂:真那么好用?Windows前世今生

hello大家好&#xff0c;这里是每天日更哒博主。 还记得我第一次说的Microsoft Dos吗&#xff1f;那期我提到一次Windows并许诺要讲讲&#xff0c;这不来了&#xff01;今天我们就详细的盘一盘最好用的系统Windows真有那么神吗&#xff1f; 注意&#xff01;以下内容包含非常…

人脸识别美颜算法实战-深度学习基础知识

深度学习与机器学习的区别: 机器学习:人类定义输入数据的特征 深度学习:机器自动找到输入数据的特征 在深度学习中,采用多层的神经网络架构来提取图像 信息,越靠近底层的神经网络提取出来的都是点、线等低维度特征, 而高维度的神经网络层则会更多地保留比如耳朵、眼睛…

MySQL事务基础知识

前言 学习/导流&#xff1a; 小林coding - 事务篇 学习意义 理解MySQL如何去处理并发问题&#xff0c;借鉴其思想存储作为应用的关键能力&#xff0c;而事务作为关系型数据库的关键概念&#xff0c;掌握很必要&#xff0c;也为分布式事务学习做奠基 相关说明 该篇博文是个…

快速搭建springboot程序

SpringBoot快速入门 观狂神讲解视频笔记 【狂神说Java】SpringBoot最新教程IDEA版通俗易懂 第一个springboot程序 使用 idea 可以快速构建一个 springboot 的项目&#xff1a; 1.创建新项目&#xff0c;选择 spring initializr&#xff08;会默认通过官网快速构建&#xff09…

【编程经验】如何学习编程语言的秘诀,编程语言选择,按需学习

大家好&#xff0c;欢迎来到停止重构的频道。最近有些朋友问我们如何学习编程、初学软件的问题&#xff0c;我们打算出几期内容聊聊我们的建议。本期聊一下如何学习编程语言。我们将压箱底的诀窍介绍给新手朋友&#xff0c;当然这仅仅是我们的一些经验&#xff0c;并不是绝对的…

连续四年第一!

近日&#xff0c;IDC发布《2022 H1中国AI云服务市场研究报告》&#xff0c;百度智能云连续四年市场份额第一&#xff0c;整体占比28.1%&#xff0c;在"人体人脸"、"图像视频"‍两个规模最大的子市场继续保持第一。‍‍ 在图像视频等多个领域蝉联市场第一 …

PLC算法系列之数值积分器(Integrator)

数值积分和微分在工程上的重要意义不用多说,闭环控制的PID控制器就是积分和微分信号的应用。流量累加也会用到。有关积分运算在流量累加上的应用,请参看下面的文章链接: SMART S7-200PLC流量累计算法实现(梯形图算法详解+优化)_RXXW_Dor的博客-CSDN博客_smart 200 流量积分…