JavaScript如何实现跨域访问(CORS)?

本文探讨了JavaScript在处理跨域请求时遇到的问题及其解决方案。介绍了同源策略、CORS(跨源资源共享)的重要性,强调了添加'Access-Control-Allow-Origin:*'到HTTP响应头以允许跨域访问的方法。同时提到了Android/iOS的WebView对跨域访问的默认支持,并提供了Android WebView配置跨域访问的简单说明。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景:

         我们访问的服务器可能要访问其他服务器的文件, 例如我们将文件存储到阿里云, 自己的服务器只缓存对应的url地址。  如果我们的服务器上部署个H5页, H5要显示阿里云的图片,  这时就遇到了跨域问题。 JavaScript默认只能访问同源的文件。

       同源策略是浏览器最重要的一种安全机制,由Netscape1995年最先提出,现在的主流浏览器都遵循这种策略。同源一般指协议,域名,端口都相同,但IE浏览器会忽略对端口的判断。RFC 6454定义了计算同源URL的算法。为了形象的描述同源URL,下表给出了特定URL是否与http://www.360.cn/weishi/index.html同源的计算结果和原因。

被比较的URL

比较结果

原因

http://www.360.cn/index.html

同源

协议和域名都相同

http://www.360.cn/weishi/updatelog.html

同源

协议和域名都相同

http://360.cn/index.html

非同源

域名不同

http://shouji.360.cn/index.html

非同源

域名不同

http://www.360.cn:8088/index.html

非同源

端口不同

https://www.360.cn

非同源

协议不同

http://www.google.com

非同源

域名不同

file:///C:/Program%20Files/360/

非同源

协议与域名都不相同


          JavaScript在访问非同源(即跨域)对象时, 浏览器会因为安全原因拒绝掉。

例如访问地址: http://123.124.21.142:8081/PDFWJDemo/web/readPdf.html?file=http://10.0.4.220:80/group2/M00/01/44/wKgBMVgES2yAdfH-AAGokQ7w640603.pdf&size=2&certpswd=MTExMTEx&contractseq=1

 

          http://123.124.21.142:8081/PDFWJDemo/web/readPdf.html是个H5页, 要下载http://10.0.4.220:80/group2/M00/01/44/wKgBMVgES2yAdfH-AAGokQ7w640603.pdf&size=2&certpswd=MTExMTEx&contractseq=1。 因为跨域了,默认无法下载对应的文件。  使用浏览器打开上述链接会提示CORS头缺少Access-Control-Allow-Origin。

  

       PS:上图用的是FireFox浏览器的插件FireBug。    

https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS 详情讲述了访问控制的原则。 实际上我们只需要在Http返回头添加Access-Control-Allow-Origin:*就可以了

Http返回头:

HTTP/1.1 200 OK
Server: openresty/1.5.8.1
Date: Mon, 17 Oct 2016 12:53:56 GMT
Content-Type: application/pdf
Content-Length: 108689
Connection: keep-alive
Last-Modified: Mon, 17 Oct 2016 03:54:20 GMT
Accept-Ranges: bytes
Access-Control-Allow-Origin: *


      Android/iOS的WebView控件都默认支持跨域访问。


以下是Android WebView配置跨域访问的方法, 默认是true,即允许跨域访问。

/**
     * Sets whether JavaScript running in the context of a file scheme URL
     * should be allowed to access content from other file scheme URLs. To
     * enable the most restrictive, and therefore secure policy, this setting
     * should be disabled. Note that the value of this setting is ignored if
     * the value of {@link #getAllowUniversalAccessFromFileURLs} is true.
     * Note too, that this setting affects only JavaScript access to file scheme
     * resources. Other access to such resources, for example, from image HTML
     * elements, is unaffected. To prevent possible violation of same domain policy
     * on {@link android.os.Build.VERSION_CODES#ICE_CREAM_SANDWICH} and earlier
     * devices, you should explicitly set this value to {@code false}.
     * <p>
     * The default value is true for API level
     * {@link android.os.Build.VERSION_CODES#ICE_CREAM_SANDWICH_MR1} and below,
     * and false for API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN}
     * and above.
     *
     * @param flag whether JavaScript running in the context of a file scheme
     *             URL should be allowed to access content from other file
     *             scheme URLs
     */
    public abstract void setAllowFileAccessFromFileURLs(boolean flag);

      解决跨域问题其实就是要配置tomcat,让http响应头添加Access-Control-Allow-Origin:*     

     原理类似于OkHttp的拦截器interceptor, 在每个响应头添加Access-Control-Allow-Origin:*

package com.example.filter;
 
import javax.servlet.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
 
public class CORSFilter implements Filter {
 
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
 
    }
 
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletResponse httpResponse = (HttpServletResponse) servletResponse;
        httpResponse.addHeader("Access-Control-Allow-Origin", "*");
        filterChain.doFilter(servletRequest, servletResponse);
    }
 
    @Override
    public void destroy() {
 
    }
}
     然后在web.xml配置拦截器Filter即可。

<filter>
    <filter-name>CorsFilter</filter-name>
    <filter-class>com.example.filter.CORSFilter</filter-class>
</filter>
 
<filter-mapping>
    <filter-name>CorsFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>


   




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值