因為 react 沒有 ajax 功能,所以使用第三方的 axios,或者用 javascript 內鍵的 fetch
axios,使用原始的 XmlHttpRequest (XHR)
fetch,ES6 加入的功能,所以舊的瀏覽器沒有這功能
※servlet
@WebServlet("*.do")
public class XxxAction extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String acc = request.getParameter("acc");
String pwd = request.getParameter("pwd");
response.getWriter().append(acc + "-" + pwd);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("POST");
this.doGet(request, response);
}
}
※寫一支測試用的 servlet
※axios
class Test extends React.Component {
handleAxios = _ => {
// GET
axios.get("abc.do?acc=aaa&pwd=pass")
.then(res => {
console.log(res)
}).catch(err => console.error(err))
// POST
const params = new URLSearchParams();
params.append('acc', 'aaa');
params.append('pwd', 'pass');
axios.post('abc.do', params) // 也可學get在後面加
.then(res => {
console.log(res)
}).catch(err => console.error(err))
// AXIOS API - GET
axios({
method:'get',
url:'abc.do?acc=aaa&pwd=pass',
})
.then(res => {
console.log(res)
});
// AXIOS API - POST
const params = new URLSearchParams();
params.append('acc', 'aaa');
params.append('pwd', 'pass');
axios({
method: 'post',
url: 'abc.do', // 也可學get在後面加
data: params
}).then(res => {
console.log(res)
});
}
render() {
return (
<button onClick={this.handleAxios}>按我</button>
)
}
}
ReactDOM.render(<Test />, document.querySelector("#xxx"));
※post 要使用 URLSearchParams 或第三方的 query-string,可參考
npm官網,但我在 npm 環境不用 URLSearchParams 也可以成功,如下:
import React, { Component } from 'react';
import axios from 'axios';
class Test extends Component {
handleAxios = _ => {
axios.post('http://localhost:8888/TestServlet/abc.do?acc=aaa&pwd=pass', {
acc:'aaa',
pwd:'pass'
})
.then(res => {
console.log(res)
}).catch(err => console.error(err))
}
render() {
return (
<button onClick={this.handleAxios}>按我</button>
)
}
}
※如果出現「 No 'Access-Control-Allow-Origin' header is present on the requested resource.」表示不能跨域,可以用瀏覽器的跨域功能 (chrome 在
這裡),或者 nginx 的跨域功能如下:
server {
listen 8888;
server_name localhost;
charset UTF-8;
location / {
proxy_pass http://localhost:10080;
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range,Token';
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}
if ($request_method = 'POST') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range,Token';
add_header 'Access-Control-Expose-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range,Token';
}
if ($request_method = 'GET') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range,Token';
add_header 'Access-Control-Expose-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range,Token';
}
}
}
※收到 localhost:8888 請求後,會導到 localhost:10080,並使用跨域功能
※同源策略:如 http://localhost
1.http
2.localhost
3.port,沒寫就是 80
以上三個一樣才算是同源,如果不同源就不允許跨域
還可參考
高手寫的
※還可以使用 query-string,尤於沒找到 browser 的下載點,所以使用 node.js
yarn add query-string
使用時只要 import queryString from 'query-string';
然後 queryString.stringify({acc:'bbb', pwd:'ccc'} 放在 post 第二個參數就搞定了,但 post 不能在第一個參數的 ? 後面加參數,否則會以第一個參數為主
※fetch
// GET
fetch('abc.do?acc=aaa&pwd=pass', {
method: 'GET'
}).then(res => {
console.log('res1=' + res);
})
.catch(err => console.error(err))
// POST
const params = new URLSearchParams();
params.append('acc', 'aaa');
params.append('pwd', 'pass');
fetch('abc.do', { // 也可學get在後面加
method: 'POST',
body: params
})
.then(res => res.json)
.then(data => {debugger;
console.log(data.message)
})
.catch(err => console.error(err))
※參考
mozilla 官網