其他教程

其他教程

Products

当前位置:首页 > 其他教程 >

CORS跨域的概念与解决方案

GG网络技术分享 2025-03-18 16:14 0


大家好,这里是关于[网站调用CDN静态资源遇到跨域问题,报错CORS error],[CORS跨域的概念与解决方案]问题的解答,希望对您有所帮助。如果你还想了解更多这方面的信息,请关注本站其他相关内容,共同学习吧!

网站调用CDN静态资源遇到跨域问题,报错CORS error

教程大全CDN,CORS error,跨域

今天给一个测试站点换了一个主题,然后在主题设置中将静态资源加载地址改成了CDN的地址(静态资源传到了CDN)。

访问发现字体文件报错CORS error

问题原因

一般情况下我们调用CDN域名上的静态资源不会出问题,都可以正常访问。

但是这个字体文件是从css脚本内引入的,浏览器是禁止从脚本内进行跨域请求的。

解决办法

在CDN域名那边服务器上声明哪些网站有权限访问哪些资源即可。

CDN设置

因为我的CDN域名套了阿里云的CDN,所以说我这需要从阿里云CDN上设置。

在阿里云CDN控制台进入:缓存配置–自定义HTTP响应头–添加

一共需要添加2条

第一条

响应头操作:增加

自定义响应头参数:Access-Control-Allow-Origin

响应头值:*

是否允许重复:允许

其中的响应头值,表示你允许哪些域名访问,“*”代表所有域名。也可以填写完整的域名。不支持多条域名,不支持泛域名添加,例如*.12345.com,仅支持域名精确匹配。

第二条

响应头操作:增加

自定义响应头参数:Access-Control-Allow-Methods

响应头值:GET,POST

是否允许重复:允许

响应头值,如果您需要同时添加POST和GET或PUT,请使用英文逗号(,)隔开。

配置完成后生效速度很快,大概十几秒,你刷新网页访问即可正常显示。

服务器设置

如果你没有使用CDN,直接是服务器的话在服务器的Nginx或者Apache上面添加即可。

不是非简单请求的且不带cookie只需2个字段即可解决跨域
add_header Access-Control-Allow-Methods *;

add_header Access-Control-Allow-Origin $http_origin;

Nginx

location / {

add_header Access-Control-Allow-Origin *;

add_header Access-Control-Allow-Methods \'GET, POST, OPTIONS\';

add_header Access-Control-Allow-Headers \'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization\';

if ($request_method = \'OPTIONS\') {

return 204;

}

}

Apache

在apache 的.hatccess中做如下设置

<FilesMatch \".(eot|ttf|otf|woff)\">

Header set Access-Control-Allow-Origin \"*\" #表示允许所有的源来访问资源,也可已指定为具体的域名,如 www.domain.com

Header set Access-Control-Allow-Methods \"*\" #允许请求的方法 GET POST等

跨域更多字段信息:不了解可以不看

add_header Access-Control-Allow-Methods *;

指定允许跨域的方法,*代表所有

add_header Access-Control-Max-Age 3600;

预检命令的缓存,如果不缓存每次会发送两次请求

add_header Access-Control-Allow-Credentials true;

带cookie请求需要加上这个字段,并设置为true

add_header Access-Control-Allow-Origin $http_origin;

表示允许这个域跨域调用(客户端发送请求的域名和端口)

$http_origin动态获取请求客户端请求的域 不用*的原因是带cookie的请求不支持*号

add_header Access-Control-Allow-Headers

$http_access_control_request_headers;

表示请求头的字段 动态获取

if ($request_method = OPTIONS){

return 200;

}

OPTIONS预检命令,预检命令通过时才发送请求

检查请求的类型是不是预检命令

参考链接:

阿里云CDN如何通过HTTP头配置跨域资源共享(CORS)

nginx解决跨域问题

CORS跨域的概念与解决方案

当我们开发小程序应用时总会多端分离,总会遇到跨域的问题,总会出现以下提示

Response to preflight request doesn't pass access control check:

No 'Access-Control-Allow-Origin' header is present on the requested resource.

Origin 'null' is therefore not allowed access.

The response had HTTP status code 40背景描述

什么是CORS跨域请求的简单请求和非简单请求

  • 简单请求
    • 请求方式:GET、POST、HEAD(注:什么是HEAD请求?HEAD请求和GET本质是一样的,但是HEAD请求不含数据,只有HTTP头部信息)
    • HTTP头部信息不超过一下几种字段:无自定义头部字段、Accept、Accept-Language、Content-Language、Last-Event-ID、Content-Type(只有三个值application/x-www-form-urlencoded、multipart/form-data、text/plain)
  • 复杂请求
    • 请求方式:PUT、DELETE
    • 自定义头部字段
    • 发送json格式数据
    • 正式通信之前,浏览器会先发送OPTION请求,进行预检,这一次的请求称为“预检请求”
    • 服务器成功响应预检请求后,才会发送真正的请求,并且携带真实数据

客户端示例

//自定义index.js

$(function(){

var pageIndex=1,moreDataFlag=true;

getOrders(pageIndex);

/*

* 获取数据 分页

* params:

* pageIndex - {int} 分页下表 1开始

*/

function getOrders(pageIndex){

var params={

url:'order/paginate',

data:{page:pageIndex,size:20},

tokenFlag:true,

sCallback:function(res) {

//请求成功处理

}

};

window.base.getData(params); //自定义请求ajax函数

}

}

服务端示例

//路由定义

Route::any('api/:version/order/paginate', 'api/:version.Order/getSummary');

class Order{

/**

* 获取全部订单简要信息(分页)

* @param int $page

* @param int $size

* @return array

* @throws \\app\\lib\\exception\\ParameterException

*/

public function getSummary($page=1, $size = 20){

$pagingOrders = OrderModel::getSummaryByPage($page, $size);

if ($pagingOrders->isEmpty()){

return [

'current_page' => $pagingOrders->currentPage(),

'data' => []

];

}

$data = $pagingOrders->hidden(['snap_items', 'snap_address'])

->toArray();

return [

'current_page' => $pagingOrders->currentPage(),

'data' => $data

];

}

}

遇到问题

提出问题

  • 如果我们访问的资源是不需要授权的,在HTTP请求头中不包含authentication头,那么以上可以正常访问了。
  • 如果该资源是需要权限验证的,那么这个时候跨域请求的预检测option请求,由于不会携带身份信息而被拒绝,浏览器会报出401错误。

解决方案

  • Tomcat配置

<filter>

<filter-name>CorsFilter</filter-name>

<filter-class>org.apache.catalina.filters.CorsFilter</filter-class>

</filter>

<filter-mapping>

<filter-name>CorsFilter</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>

  • Apache配置

Header always set Access-Control-Allow-Origin "http://waffle"

Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS"

Header always set Access-Control-Allow-Credentials "true"

Header always set Access-Control-Allow-Headers "Authorization,DNT,User-Agent,Keep-Alive,Content-Type,accept,origin,X-Requested-With"

RewriteCond %{REQUEST_METHOD} OPTIONS

RewriteRule ^(.*)$ $1 [R=200,L]

  • Nginx配置

add_header 'Access-Control-Allow-Methods' 'GET,OPTIONS,PUT,DELETE' always;

add_header 'Access-Control-Allow-Credentials' 'true' always;

add_header 'Access-Control-Allow-Origin' '$http_origin' always;

add_header 'Access-Control-Allow-Headers' 'Authorization,DNT,User-Agent,Keep-Alive,Content-Type,accept,origin,X-Requested-With' always;

if ($request_method = OPTIONS ) {

return 200;

}

  • ThinkPHP5配置

1.全局考虑为所有接口解决跨域

2.使用拦截器-AOP

3.TP5全局拦截请求-应用行为

//tag.php

<?php

// 应用行为扩展定义文件

return [

// 应用初始化

'app_init' => [

// 'app\\\\api\\\\behavior\\\\CORS'

],

// 应用开始

'app_begin' => [],

// 模块初始化

'module_init' => [

],

// 操作开始执行

'action_begin' => [],

// 视图内容过滤

'view_filter' => [],

// 日志写入

'log_write' => [],

// 应用结束

'app_end' => [],

];

//CORS.php

<?php

namespace app\\api\\behavior;

use think\\Response;

class CORS

{

public function appInit(&$params)

{

header('Access-Control-Allow-Origin: *');

header("Access-Control-Allow-Headers: token,Origin, X-Requested-With, Content-Type, Accept");

header('Access-Control-Allow-Methods: POST, GET, OPTIONS');

if(request()->isOptions()){

exit();

}

}

}

标签: 小程序

提交需求或反馈

Demand feedback