目录
一、使用 crossorigin 属性解决 jsonp 跨域
二、JSX+React+Babel “通过 script 标签引入 react 组件” 报错跨域
一、使用 crossorigin
属性解决 jsonp 跨域
如果你通过 CDN 的方式引入 React,我们建议你设置 crossorigin
属性:
<script crossorigin src="..."></script>
如果给跨域<script>
标签添加了crossorigin
属性,且服务器端没有设置Access-Control-Allow-Origin 响应头,就会出现以下错误:
Access to XMLHttpRequest at 'file:///Users/temporary/learn-react/3JSX/like_btn.js' from origin 'null' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, chrome-untrusted, https.
所以,建议你验证使用的 CDN 是否设置了 Access-Control-Allow-Origin: *
HTTP 请求头。
crossorigin属性
crossorigin 属性不止可以用于<script>
标签,还可以用与<img>
,<video>
等标签,
用于配置 CORS 的请求数据,见下表,
Keyword | State | Request Mode | Credentials Mode |
---|---|---|---|
the attribute is omitted | No CORS | "no-cors" | "omit" |
"" | Anonymous | "cors" | "same-origin" |
"anonymous" | Anonymous | "cors" | "same-origin" |
"use-credentials" | Use Credentials | "cors" | "include" |
不同的crossorigin
值,指定了不同的Request Mode 和 Credentials Mode。
二、JSX+React+Babel “通过 script 标签引入 react 组件” 报错跨域
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>jsx+react+babel</title>
</head>
<body>
<h2>hello world</h2>
<div id="box"></div>
<!-- 加载 React 和 ReactDom -->
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<!-- 加载 JSX -->
<script crossorigin src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<!-- 加载 React 组件-->
<script crossorigin type="text/babel" src="like_btn.js"></script>
</body>
</html>
react 组件:
// like_btn.js
class LikeButton extends React.Component {
constructor(props) {
super(props);
this.state = { liked: false };
}
render() {
if (this.state.liked) {
return 'You liked this.';
}
return (
<button onClick={() => this.setState({ liked: true })}>
Like
</button>
);
}
}
ReactDOM.render(<LikeButton />, document.querySelector('#box'));
此时,在浏览器中运行该页面,发现产生了跨域!!!报错如下:
Access to XMLHttpRequest at 'file:///Users/temporary/learn-react/3JSX/like_btn.js' from origin 'null' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, chrome-untrusted, https.
这就是 Bable 的限制了,Babel 官网里对于 JSX+React 给出了使用建议:https://www.babeljs.cn/docs/
简而言之,如果想要使用 JSX+React+Babel 通过 script 标签引入 react 组件,就必须结合 webpack 安装 “@babel/preset-react” 包,否则 Babel 没有办法解析组件里的 JavaScript 代码。
换句话说,如果直接在 html 中尝试使用 JSX+React+Babel,请不要组件化,必须将 JavaScript 代码写在 <script type="text/babel"></script> 中。具体实现如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>jsx+react+babel</title>
</head>
<body>
<h2>hello world</h2>
<div id="box"></div>
<!-- 加载 React 和 ReatDom -->
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<!-- 加载 JSX -->
<script crossorigin src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<script type="text/babel">
class LikeButton extends React.Component {
constructor(props) {
super(props);
this.state = { liked: false };
}
render() {
if (this.state.liked) {
return 'You liked this.';
}
return (
<button onClick={() => this.setState({ liked: true })}>
Like
</button>
);
}
}
ReactDOM.render(<LikeButton />, document.querySelector('#box'));
</script>
</body>
</html>