對于我的小Javascript應用程式,我用CGI寫了服務器端的API函式。
。我把它做得非常簡單,完整的例子腳本看起來是這樣的:
#!/usr/bin/env perl
use strict; use warnings; use 5.014;
use CGI;
use JSON;
use Data::Dumper;
my $q = new CGI;
my %p = $q->Vars;
_api_response()。
sub _api_response{
my ( $error ) = @_;
my $res;
my $status = 200;
my $type = 'application/json';
my $charset = 'utf-8';
if ( $error ) {
$status = 500;
$res->{data} = {
status => 500,
};
$res->{error} = {
error => '失敗'。
message => $error,
detail => Dumper \%p,
};
} else {
$res->{data} = {
status => 200,
};
}
print $q->header(
-status => $status。
-type => $type。
-charset => $charset,
);
my $body = encode_json( $res ) 。
print $body。
}
當我用fetch從JS腳本中呼叫它時,它沒有得到回應體。如果我從開發者工具/網路中檢查,它也沒有回應體。如果我在瀏覽器中輸入相同的URL,它會顯示JSON體。如果我使用curl作為
curl -v 'https://example.com/my_api? api=1;test=2;id=32'
回應似乎也有正確的主體:
< HTTP/2 200
< date: Mon, 13 Sep 2021 14:04:42 GMT
< server: Apache/2.4.25 (Debian)
< set-cookie: example=80b7b276. 5cbe0f250c6c7; path=/; expires=Thu, 08Sep-22 14: 04:42 GMT
< cache-control: max-age=0, nostore
< 內容型別: application/json; charset=utf-8
<
* 連接 #0 to host example.com left intact
{"data":{"status":200}}
為什么fetch不把它看作是一個主體?
為了完整起見,我還包括JS部分:
async function saveData(url = ''/span>, data = {}) {
const response = await fetch(url, {
method: 'GET',
mode: 'no-cors',
cache: 'no-cache',
credentials: '省略'。
headers: {
'Content-Type': 'application/json'。
},
redirect: 'follow',
referrerPolicy: 'no-referrer'。
});
console.log(response); //body is null.
return response.json()。
使用該函式為:
saveData('https://example.com/my_api?api=1; test=2;id=32', { answer: 42 })
.then(data => {
console.log(data);
})
.catch( error => {
console.error( error ); })。
});。
在控制臺我看到錯誤:
SyntaxError: 不料end的input。
這個錯誤的一個可能原因是空的JSON字串。
uj5u.com熱心網友回復:
我能夠重現你的問題,然后我能夠修復它。
這是一個 CORS 問題。你需要在前端和后端都啟用 CORS。
在前端,你需要在你的頁面的<head>中用元標簽設定內容安全策略:
< meta http-equiv="Content-Security-Policy" content="default-src *。style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval' http: //localhost">
(別忘了把localhost改成你真正的域名。)
在后面你需要添加CORs頭:
在后面你需要添加CORs頭。
print $q->header(
-status => $status。
-type => $type。
-charset => $charset。
-access_control_allow_origin => '*', # <-- 添加這一行。
);
附帶說明一下,你傳入fetch的設定都是不必要的。因為你正在等待回應,然后回傳另一個承諾,所以真的沒有理由讓它成為一個異步函式。
在你準備對未使用的data引數進行處理之前,下面的代碼就足夠了:
function saveData(url = ' ', data = {}) {
return fetch(url)。 then(response=>response.json()。
}
uj5u.com熱心網友回復:
你也要為response.json()進行等待。
嘗試return await response.json();,而不是return response.json();
uj5u.com熱心網友回復:
分號在某些情況下不再被接受為引數分隔符,這可以解釋不一致的行為。試試用安培爾:
saveData('https://example.com/my_api?api=1&test=2&id=32'/span>, { answer: 42 })
.then(data => {
console.log(資料)。
})
.catch( error => {
console.error( error ) 。
});
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/328603.html
標籤:
