www.111cn.net 更新:2015-01-07 编辑:flyfox 来源:转载

跨域在开发中一些是一个比较常见的问题虽然有json或者xml来解决,现在html5开始流行了,我们可以通过Access-Control-Allow-Origin解决跨域问题,下面一起来看看。
 

A.abc.com 发起一个到 abc.com/B 的ajax请求,也会有跨域的问题。之所以会有跨域问题,实则是因为www.abc.com其实同A.abc.com一样,也是一个二级域名,而非一级域名(一级域名是http://abc.com)。

URL 说明 是否允许通信
http://www.a.com/a.jshttp://www.a.com/b.js 同一域名下 允许
http://www.a.com/lab/a.jshttp://www.a.com/script/b.js 同一域名下不同文件夹 允许
http://www.a.com:8000/a.jshttp://www.a.com/b.js 同一域名,不同端口 不允许
http://www.a.com/a.jshttps://www.a.com/b.js 同一域名,不同协议 不允许
http://www.a.com/a.jshttp://170.32.82.74/b.js 域名和域名对应ip 不允许
http://www.a.com/a.jshttp://script.a.com/b.js 同一域名,不同二级域名 不允许
http://www.a.com/a.jshttp://a.com/b.js 二级域名和一级域名 不允许(cookie这种情况下也不允许访问)
http://www.b.com/a.jshttp://www.a.com/b.js 不同域名 不允许

对于是否允许跨域,更详细的说明可以看下表:

有了对跨域的基本概念了解后,就可直接进入这篇文章的主题了。

赞助商链接
解决方法:

若在接收请求的服务端abc.com/B页面用的是php语言,则在页面中加入:

// 指定可信任的域名来接收响应信息,推荐
<?php  header('Access-Control-Allow-Origin:http://A.abc.com'); ?>
或加入

// 使用通配符 * ,表示当前服务端通话任何域名发起请求,不推荐
<?php header('Access-Control-Allow-Origin:*'); ?>
就这样在服务端简单加一句响应头responese headers声明,一个跨域请求就不会被浏览器的同源安全策略所阻止了!

用chrome调试工具Network ajax请求查看面板中可以看到,类似如下截图:cors

需要注意的是:

添加响应头responese headers时,允许跨域请求的域名带不带斜杠/还是有区别的,带斜杠/会报错:
XMLHttpRequest cannot load  abc.com/B. The 'Access-Control-Allow-Origin' header has a value 'http://A.abc.org/' that is not equal to the supplied origin. Origin 'http://A.abc.org' is therefore not allowed access.

header('Access-Control-Allow-Origin:*');是html5新增的一项标准功能,因此 IE10以下 版本的浏览器是不支持 的,因此,如果要求兼容IE9或更低版本的ie浏览器,会导致使用此种方式的跨域请求以及传递Cookie的计划夭折,最终还得回归JSONP(目前主流的处理方式是使用JSONP,易于实现,兼容性好,可查的资料也很多。)

跨域解决后,如果还要操作Cookie,还得继续补增响应头:

<?php  header('Access-Control-Allow-Credentials:true'); ?>
需要将 XMLHttpRequest 对象的 withCredentials 属性设置为 true,JQuery1.5.1+ 就开始提供了相应的字段,使用方式如下:

$.ajax({
url:"B.abc.com",
xhrFields:{
withCredentials:true
},
crossDomain:true
});
哦也~ 收到 Cookie 了。

设置 withCredentials 为 true 的请求中会包含 A.abc.com端的所有Cookie,这些Cookie仍然遵循同源策略,所以,你只能访问其中和 abc.com/B同根域的Cookie,而无法访问其他域的Cookie。

Access-Control-Allow-Origin实则是html5 Cross-Origin Resource Sharing实现的最重要的一点参数配置。
Cross-Origin Resource Sharing,跨域资源共享,简称 CORS,可以作为一种跨域请求以及响应的解决方案。

附:

禁用chrome本地安全策略,不用配服务器环境也能发起ajax请求:
chrome 桌面快捷键 右键属性 在快捷方式标签下的“目标”框中加入 --disable-web-security,重启浏览器即可

html5实现文章阅读进度指示器例子

www.111cn.net 更新:2015-01-03 编辑:angel 来源:转载
下面我们为各位整理一个html5实现文章阅读进度指示器例子,希望这个例子可以帮助到各位。
 
近期我发现很多网站增加了一种能够显示出当前阅读位置的指示器(你阅读了多少依赖于你在这篇文章上向下拉动滚动条拉动了多少)。通常,这种指示器被用在博客的文章或者是长表单上,用于帮助阅读着了解他们还有多少就能完成这篇文章或者表单。

问题

要建立一个阅读位置指示器,我们需要回答如下两个问题:

  1. 网页的长度是多少?网页的长度与文档当前的长度相同,这可以通过javascript计算出来。
  2. 用户当前的阅读位置在哪?要获取用户当前的阅读位置可能需要进入用户的思维中去寻找了,在我们所能处理的给定的技术范围之内,这看起来像是人工智能和不可能实现的。
这让我们不得不去使用一种完全不同的方式去解决这个问题。

原则

这项技术的原则是基于用户不得不滚动滚到条到页面的底部的简单的一个事实。一旦用户滚动滚到条到了页面的底部,我们可以得到用户已经阅读完成了这篇文章。解决获取当前用户阅读位置这个问题的关键看起来就是解决滚动条滚动事件了。

假设用户从页面顶部开始阅读,而且在到达页面底部之前他只会一次性的滚动滚动条,我们将会回答下列问题:
  1. 用户需要滚动多久才能滚到到页面的底部?隐藏在用户视点之下的页面部分实际上就反映了用户需要滚动到页面底部的实际数量。这将成为max属性。
  2. 用户已经滚动了多少部分?这个可以通过文档内容在窗口中的位置到顶部的垂直偏移来进行计算,这个将成为我们的value属性。
上图中的例子模拟了用户滚动窗口的行为,当用户向下滚动滚动条的时候,垂直偏移增加。
 
在浏览器的上下文中,document和window是两个不同的对象。window是一个浏览器中可见的区域(在上面例子中蓝色窗口中的部分),document实际上是window中载入的页面(例子中当前滚动的灰色框)。

标记

让我们从最基本的标记开始:

<progress value="0"></progress>
显式的指定value属性是非常重要的。否则,我们的进度条将会处于一个不可知的状态。我们不想给进度条的不可知状态添加不必要的css样式。因此,我们选择通过添加一个初始值以忽略该状态。刚开始,用户从页面的顶部开始阅读,因此,开始值被设置为0,默认情况下,最大的值是1(如果没有指定的话)。
要得到max属性正确的值,我们需要从document高度中减去window的高度。这只能通过javascript来进行处理,我们将在后面的部分再讨论它。
标记在文档中的位置是重度依赖于html文档中剩余元素是怎么放置的。通常,如果你的文档中没有固定位置(fixed)的容器的话,你可以把进度条元素放在body元素内部其它所有元素的顶部。
<body>
  <progress value="0"></progress>   <!--------------------------------
  这里放额外的标记
  --------------------------------->
</body>

为指示器添加样式

我们想要让我们的指示器总是在页面的顶部显示,即使用户滚动窗口也是这样,我们将progress元素设置为fixed。另外,我们应该希望进度条的背景是transparent(透明)的,这样在页面滚动时就不会创建一个空的进度条阻碍用户视线。同时,这也会帮助我们处理好在javascript被禁用的时候浏览器的表现,后面我们会介绍这一点。

progress {
  /* Positioning */
  position: fixed;
  left: 0;
  top: 0;   /* Dimensions */
  width: 100%;
  height: 5px;   /* Reset the appearance */
  -webkit-appearance: none;
     -moz-appearance: none;
          appearance: none;   /* Get rid of the default border in Firefox/Opera. */
  border: none;   /* Progress bar container for Firefox/IE10+ */
  background-color: transparent;   /* Progress bar value for IE10+ */
  color: red;
}
对于Blink/Webkit/Firefox, 我们需要使用厂商指定的前缀添加到进度条样式上,这里用来给进度条添加颜色。
progress::-webkit-progress-bar {
  background-color: transparent;}progress::-webkit-progress-value {
  background-color: red;
}
progress::-moz-progress-bar {
  background-color: red;
}

交互

用javascript计算浏览器的width/height属性是非常麻烦的,同时,在不同内核的浏览器中的表现是非常可怕的。幸运的是,jquery抽象了这些复杂的操作,使得我们可以以清晰的方法去计算window和document的度量。因此,在接下来的内容中,我们将会通过jquery来处理与用户之间的交互。

在开始之前,不要忘记在文档中添加jquery的类库。
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
我们需要用jquery去获取进度条元素的max和value属性。
max-它的值是通过document的高度减去window的高度获取的页面未显示出来的部分的高度。
var winHeight = $(window).height(),
  docHeight = $(document).height();
  max = docHeight - winHeight;
$(progress).attr('max', max);
value-刚开始,value属性的值是0(已经在标记中指出了)。然后,随着用户滚动滚动条,垂直方向文档到到窗口的高度将会增加,如果滚动条在页面的最顶部,或者是不可滚动的,偏移将会是0。
var value = $(window).scrollTop();
$(progress).attr('value', value);
提示: 代替使用$(document).height(),我们可以使用诸如section,article,或者是div放置文章的内容进行计算,这样可以获取更高的阅读位置的精确度。当我们的文章含有评论内容和页面的其它组成部分占用了页面超过50%的比例的时候,这一点是非常有用的。
现在,每一次用户滚动滚动条,我们需要重新计算value的值,并设置进度条的value属性。注意的是,max属性是不变的。
$(document).on('scroll', function() {
  value = $(window).scrollTop();
  progressBar.attr('value', value);
});
用户滚动的方向是不重要的,因为我们每次都会重新计算value的值(y方向的偏移)。
我们的代码需要在dom载入之后执行,这一点是非常重要的,否则,过早的计算window/document的高度会产生不可预知的结果。
$(document).on('ready', function() {  
  var winHeight = $(window).height(), 
      docHeight = $(document).height(),
      progressBar = $('progress'),
      max, value;   /* Set the max scrollable area */
  max = docHeight - winHeight;
  progressBar.attr('max', max);   $(document).on('scroll', function(){
     value = $(window).scrollTop();
     progressBar.attr('value', value);
  });
});
(或者是可以让这段代码在页面的底部加载,这样可以跳过使用document的ready调用。

浏览器兼容性

这需要我们建立一个能够在不同浏览器中能够拥有相同表现的阅读位置指示器,我们建立的这个阅读位置指示器能够在所有良好支持html5进度条元素的浏览器中正常工作。但是,这种支持仅在firefox16+,opera 11+, chrome,safari 6+,ie 10+的浏览器上可用。opera 11和12不支持改变进度条的颜色。因此,我们的进度条将会是默认的绿色。

边界问题

在很多情况下,我们上述的代码可能会崩溃或者是不能够正确的指示出用户阅读的位置,让我们看看这些情况。

document高度<=window高度

我们的代码假设了document的高度总是大于window的高度,但是,实际情况并不总是这样的。幸运的是,浏览器会帮助我们处理这种情况,当document的高度比window的高度小的时候,浏览器会返回window的高度。因此,docHeight和winHeight是相同的。

max = docHeight - winHeight; // equal to zero.
这会让进度条的max和value属性都是0。
<progress max="0" value="0"></progress>
因此,我们的进度条仍然是空的,而且我们的背景是透明的,这样页面中就不会出现进度条。这产生一种感觉就是当用户的视点能够充满整个页面的时候,我们没有必要再添加一个指示器了。
而且,因为文档的高度不会超过window的高度,所以滚动事件也是不会被触发的。因此,不需要做任何处理,我们的代码再处理这个边界问题的时候是足够健壮的。

用户改变window的尺寸

当用户改变window的尺寸的时候,window和document的高度将会发生改变。这意味着我们必须要重新计算max和value属性以反映出指示器当前正确的位置。我们将会通过resize事件处理器重新计算正确的位置。

$(window).on('resize', function() {
  winHeight = $(window).height(),
  docHeight = $(document).height();   max = docHeight - winHeight;
  progressBar.attr('max', max);   value =  $(window).scrollTop();
  progressBar.attr('value', value);
});

javascript被禁用

当javascript被禁用的时候,我们的进度条将会有一个最大值为1,当前默认值为0。

<progress max="1" value="0"></progress>
这意味着我们的进度条将会依旧是空的,而且不会影响到页面的其它部分。这样做是很好的,因为页面中没有指示器对于读者来说并不是一个很大的缺失。

旧的浏览器兼容

旧的不支持html5的进度条元素的浏览器将会忽略掉progress标记。然而,对于一些站点来说,提供始终如一的体验是非常重要的(该方案略,详见原文)。

性能

通常,给滚动事件添加事件处理器被认为是非常不好的实践,因为每次滚动的时候,浏览器都会试图去重绘出现的内容。在我们的例子中,dom的结构和样式是比较简单的,在页面滚动的时候不会有任何明显会注意到的延迟或者是滞后。然而,当我们放大这里,在我们的拥有复杂的dom结构的站点中实现的时候,滚动的体验将会是产生很多性能的缺失。

如果滚动性能成为了你面临的一个难以客服的大问题的话,你应该尽可能避免这个特性的使用或者尝试优化代码以避免不必要的重绘。

造成的困惑

我不是一个UX专家,但是在一些情况下,我们的指示器的位置和外观可能会是模棱两可的并且会误导用户。ajax驱动的站点比如Medium,Youtube等,使用相似的进度条指示下一个页面载入的进度。Chrome移动浏览器本地使用蓝色的进度条作为页面加载进度。现在,如果你在框架上添加一个进度指示器,我保证肯定有很多人需要花费很长时间去理解这个顶部的指示器是有什么作用的。

你必须权衡这个是否对你的用户是有好处的。
 
优点:
  1. 语义准确
  2. 没有引入书math库或者是复杂的计算
  3. 最小化必要的标记
  4. 无缝的兼容不支持html5进度条的浏览器
  5. 无缝的兼容禁用javascript的浏览器
缺点:
  1. 跨浏览器样式是复杂的
  2. 老浏览器的兼容性依赖于传统的div/span(s)标记技术去实现
  3. 性能影响(复杂的dom结构情况下)
  4. 与页面加载进度的进度条容易混淆,让用户很难理解
现在低版本的ie浏览器是不兼容HTML5的,那么我们要如何让它兼职呢?下面来介绍的简单一个IE兼容实现HTML5的placeholder处理办法。
 

只要用过表单中的placeholder的前端同学,就会发现它的强大之处,再也不用写一些超多事件的JS来实现,而这个属性却不能被脑残的IE低版本所支持,我们只能想一些办法来变通一下。

一、JQ方式实现(不支持password类型)

 代码如下 复制代码
<script type="text/javascript">   
  if( !('placeholder' in document.createElement('input')) ){   
    $('input[placeholder],textarea[placeholder]').each(function(){    
      var that = $(this),    
      text= that.attr('placeholder');    
      if(that.val()===""){    
        that.val(text).addClass('placeholder');    
      }    
      that.focus(function(){    
        if(that.val()===text){    
          that.val("").removeClass('placeholder');    
        }    
      })    
      .blur(function(){    
        if(that.val()===""){    
          that.val(text).addClass('placeholder');    
        }    
      })    
      .closest('form').submit(function(){    
        if(that.val() === text){    
          that.val('');    
        }    
      });    
    });    
  }   
</script>

上面的方法缺点就是不能支持password类型的文本框,目前还没有很好的解决办法。

二、使用JQ插件jquery.placeholer.js

Github地址:https://github.com/tonitech/jquery.placeholder.js   引入到页面然后执行下面的代码:

 代码如下 复制代码
<script type="text/javascript">
$(function() {
 $('input, textarea').placeholder();
});
</script>

这个方法比较简单,唯一令我不喜欢的是它要求jquery版本1.3到1.8,而我现在在项目中使用的是1.11,所以无奈我没有使用,如果你的项目使用的是1.3-1.8版本的,可以尝试下。

三、原生JS通过Label标签实现

 代码如下 复制代码
<script type="text/javascript">
var funPlaceholder = function(element) {  
    //检测是否需要模拟placeholder  
    var placeholder = '';  
    if (element && !("placeholder" in document.createElement("input")) && (placeholder = element.getAttribute("placeholder"))) {  
        //当前文本控件是否有id, 没有则创建  
        var idLabel = element.id ;  
        if (!idLabel) {  
            idLabel = "placeholder_" + new Date().getTime();  
            element.id = idLabel;  
        }  
        //创建label元素  
        var eleLabel = document.createElement("label");  
        eleLabel.htmlFor = idLabel;  
        eleLabel.style.position = "absolute";  
        //根据文本框实际尺寸修改这里的margin值  
        eleLabel.style.margin = "8px 0 0 3px";  
        eleLabel.style.color = "graytext";  
        eleLabel.style.cursor = "text";  
        //插入创建的label元素节点  
        element.parentNode.insertBefore(eleLabel, element);  
        //事件  
        element.onfocus = function() {  
            eleLabel.innerHTML = "";  
        };  
        element.onblur = function() {  
            if (this.value === "") {  
                eleLabel.innerHTML = placeholder;  
            }  
        };  
        //样式初始化  
        if (element.value === "") {  
            eleLabel.innerHTML = placeholder;  
        }  
    }  
};  
funPlaceholder(document.getElementsByName("username")[0]);  
funPlaceholder(document.getElementsByName("password")[0]);  
</script>

这个方法我现在在用,而且还是原生的,感觉很不错,推荐给大家。

 
 
 

HTML5中Access-Control-Allow-Origin解决跨域问题的更多相关文章

  1. Django框架深入了解_05 (Django中的缓存、Django解决跨域流程(非简单请求,简单请求)、自动生成接口文档)

    一.Django中的缓存: 前戏: 在动态网站中,用户所有的请求,服务器都会去数据库中进行相应的增,删,查,改,渲染模板,执行业务逻辑,最后生成用户看到的页面. 当一个网站的用户访问量很大的时候,每一 ...

  2. springboot中通过cors协议解决跨域问题

    1.对于前后端分离的项目来说,如果前端项目与后端项目部署在两个不同的域下,那么势必会引起跨域问题的出现. 针对跨域问题,我们可能第一个想到的解决方案就是jsonp,并且以前处理跨域问题我基本也是这么处 ...

  3. 在django中解决跨域AJAX

    由于浏览器存在同源策略机制,同源策略阻止从一个源加载的文档或脚本获取另一个源加载的文档的属性. 特别的:由于同源策略是浏览器的限制,所以请求的发送和响应是可以进行,只不过浏览器不接收罢了. 浏览器同源 ...

  4. Vue 本地代理 纯前端技术解决跨域

    vue-axios获取数据很多小伙伴都会使用,但如果前后端分离且后台没设置跨域许可,那要怎样才能解决跨域问题? 常用方法有几种: 通过jsonp跨域 通过修改document.domain来跨子域 使 ...

  5. ASP.Net中关于WebAPI与Ajax进行跨域数据交互时Cookies数据的传递

    本文主要介绍了ASP.Net WebAPI与Ajax进行跨域数据交互时Cookies数据传递的相关知识.具有很好的参考价值.下面跟着小编一起来看下吧 前言 最近公司项目进行架构调整,由原来的三层架构改 ...

  6. html5中的postMessage解决跨域问题

    解决跨域问题的方法有很多,如:图像ping(简单).jsonp(缺点是不能实现跨域post).CROS(CORS的本质让服务器通过新增响应头Access-Control-Allow-Origin,通过 ...

  7. Spring Boot中通过CORS解决跨域问题

    今天和小伙伴们来聊一聊通过CORS解决跨域问题. 同源策略 很多人对跨域有一种误解,以为这是前端的事,和后端没关系,其实不是这样的,说到跨域,就不得不说说浏览器的同源策略. 同源策略是由Netscap ...

  8. [转]html5: postMessage解决跨域和跨页面通信的问题

    [转]html5: postMessage解决跨域和跨页面通信的问题 平时做web开发的时候关于消息传递,除了客户端与服务器传值,还有几个经常会遇到的问题: 多窗口之间消息传递(newWin = wi ...

  9. Access control allow origin 简单请求和复杂请求

    原文地址:http://blog.csdn.net/wangjun5159/article/details/49096445 错误信息: XMLHttpRequest cannot load http ...

随机推荐

  1. .Net应用程序 参照的组合没有安装在您的系统中。 HRESULT: 0x800736B3

    同事打开一个.Net的应用程序链接,一直无法启动.错误信息为: 啓用xx.application 時發生例外狀況. 已偵測到下列失敗訊息:參照的組合沒有安裝在您的系統中. (發生例外狀況於 HRESU ...

  2. 解决oninput在输入中文时,会获取拼音的问题

    (1)起因:在今天做项目测试的时候发现的问题,在用微软自带的输入法的时候,输入中文,文本框会获得拼音 如图所示: (2)解决办法:经过一段时间的百度查找,最后通过这篇文章找到了解决的方法,这里给出网址 ...

  3. AJPFX的监管与执照

      AJPFX受到英国金融行为监管局(FCA)授权和监管. 英国FCA是目前世界上金融服务最完善.最健全的监管机构,英国FCA对所有在其境内注册的金融服务机构进行严格的监管. 英国金融行为监管局(FC ...

  4. Day37 多进程

    什么是进程 进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础.在早期面向进程设计的计算机结构中,进程是程序的基本执行实体: ...

  5. Docker registry 私有仓库镜像查询、删除、上传、下载 shell

    #Docker官方私有仓库registry #官方只提供了API接口,不方便使用,就写了个shell #docker-registry安装配置http://www.cnblogs.com/elvi/p ...

  6. Design-341. Flatten Nested List Iterator

    Given a nested list of integers, implement an iterator to flatten it. Each element is either an inte ...

  7. 如何正确的加载和执行 JavaScript 代码

    无论当前 JavaScript 代码是内嵌还是在外链文件中,页面的下载和渲染都必须停下来等待脚本执行完成.JavaScript 执行过程耗时越久,浏览器等待响应用户输入的时间就越长.浏览器在下载和执行 ...

  8. easyui datagrid 清除缓存方法

    easyui datagrid 清除缓存方法 今天在项目中做了一个添加合同编号页面,添加合同编号了,在datagrid列表上没有显示刚才添加的那个合同编号. 这个问题在IE上特别明显. 原因是添加编号 ...

  9. jmeter -- 在beanshell中拿到请求body参数和header参数

    beanshell: import org.apache.jmeter.config.Arguments; import org.apache.jmeter.protocol.http.control ...

  10. MySQL 5.7.14 win10安装

    1. 下载: http://dev.mysql.com/downloads/mysql/