[更新:事实证明,这只发生在 Safari 上,而 Chrome 或 Firefox 上则不会]
这个问题已经在网络上发布了一百万次,但是所有的提示、提示和技巧(cors、内容类型等)都没有给我带来解决方案。
为了隔离,我正在使用一个非常小的Python“网络服务器”来测试它:
def handle_request(request):
print( "REQUEST TO HANDLE")
print( request)
if request.startswith("GET /checkdo.html HTTP/1.1"):
if checkdo is not None:
response = "HTTP/1.1 200 OK\r\n"
response += "Content-Type: text/html\r\n"
response += "Content-Length: {}\r\n".format(len(checkdo))
response += "\r\n" + checkdo
else:
response = "HTTP/1.1 404 Not Found\r\n\r\n"
response += "No data found for the token."
elif request.startswith("POST /checkdo-post HTTP/1.1"):
token = extract_token(request)
if is_authorized(token):
data = request.split("\r\n")[-1]
print( "DATA")
print( data)
store_data(token, data)
response = "HTTP/1.1 200 OK\r\n\r\n"
response += "Data saved successfully!"
else:
response = "HTTP/1.1 403 Forbidden\r\n\r\n"
response += "Unauthorized access!"
else:
response = "HTTP/1.1 404 Not Found\r\n\r\n"
return response
def start_server():
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address = ('', 8080)
server_socket.bind(server_address)
server_socket.listen(1)
print("Server listening on port 8080...")
while True:
client_socket, client_address = server_socket.accept()
print("Received connection from:", client_address)
rawrequest = client_socket.recv(4096)
print( "RECEIVE")
print( rawrequest)
request = rawrequest.decode('utf-8')
response = handle_request(request)
print( "RESPOND")
print( response)
client_socket.sendall(response.encode('utf-8'))
client_socket.close()
if __name__ == "__main__":
start_server()
基本上,这消除了后端的所有智能,它现在只是一个 TCP 套接字。
GET 有效。但是当我在网页 javascript 中发送 POST 时:
const saveToServer = (remindersToSave) => {
const myHeaders = new Headers();
const myToken = getToken();
myHeaders.append( "Accept", "application/json");
myHeaders.append( "Content-type", "application/json; charset=UTF-8");
//myHeaders.append( "Content-type", "application/x-www-form-urlencoded");
myHeaders.append( "Authorization", myToken);
const myURL = window.location.protocol + "//" + window.location.host + "/checkdo-post";
const myData = JSON.stringify(remindersToSave);
console.log( "POST: " + myURL);
console.log( "DATA: " + myData);
(async () => {
const rawResponse = await fetch(myURL, {
method: 'POST',
headers: myHeaders,
body: myData
});
console.log(rawResponse);
})();
}
我在浏览器控制台中注意到:
[Log] POST: http://localhost:8080/checkdo-post (checkdo.html, line 81)
[Log] DATA: [{"name":"A Task","subtasks":[{"name":"A Subtask","lastDone":0},{"name":"A Subtask","lastDone":1687125600000},{"name":"A Subtask","lastDone":1687125600000}],"lastDone":0}] (checkdo.html, line 82)
[Log] Response {type: "basic", url: "http://localhost:8080/checkdo-post", redirected: false, status: 200, ok: true, …} (checkdo.html, line 96)
基本上,我的 JavaScript 代码表示它将通过 fetch 发送 POST 请求。
但是在 python nano-“服务器”端我看到了
Received connection from: ('127.0.0.1', 55691)
RECEIVE
b'POST /checkdo-post HTTP/1.1\r\nHost: localhost:8080\r\nAccept: application/json\r\nAuthorization: B4Kr6H9AqPsuKfpc3RuGimafae8Xc6mT9hbsRmzz\r\nSec-Fetch-Site: same-origin\r\nAccept-Language: en-GB,en;q=0.9\r\nAccept-Encoding: gzip, deflate\r\nSec-Fetch-Mode: cors\r\nContent-Type: application/json; charset=UTF-8\r\nOrigin: http://localhost:8080\r\nContent-Length: 171\r\nUser-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.5 Safari/605.1.15\r\nReferer: http://localhost:8080/checkdo.html\r\nConnection: keep-alive\r\nSec-Fetch-Dest: empty\r\nCookie: default-theme=ngax\r\n\r\n'
REQUEST TO HANDLE
POST /checkdo-post HTTP/1.1
Host: localhost:8080
Accept: application/json
Authorization: B4Kr6H9AqPsuKfpc3RuGimafae8Xc6mT9hbsRmzz
Sec-Fetch-Site: same-origin
Accept-Language: en-GB,en;q=0.9
Accept-Encoding: gzip, deflate
Sec-Fetch-Mode: cors
Content-Type: application/json; charset=UTF-8
Origin: http://localhost:8080
Content-Length: 171
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.5 Safari/605.1.15
Referer: http://localhost:8080/checkdo.html
Connection: keep-alive
Sec-Fetch-Dest: empty
Cookie: default-theme=ngax
DATA
RESPOND
HTTP/1.1 200 OK
Data saved successfully!
收到的请求中没有数据。鉴于我的“Web 服务器”实际上不是 Web 服务器,它只是一个原始 tcp 套接字,所以一定是我的 Safari 浏览器拒绝发送 POST 中的数据。但无论我做什么,我都无法解决这个问题。
我确定它是浏览器:
curl -i -X POST -H 'Content-Type: application/json' -d '{"name": "New item", "year": "2009"}' http://localhost:8080/checkdo-post
结果:
b'POST /checkdo-post HTTP/1.1\r\nHost: localhost:8080\r\nUser-Agent: curl/8.0.1\r\nAccept: */*\r\nContent-Type: application/json\r\nContent-Length: 36\r\n\r\n{"name": "New item", "year": "2009"}'
REQUEST TO HANDLE
POST /checkdo-post HTTP/1.1
Host: localhost:8080
User-Agent: curl/8.0.1
Accept: */*
Content-Type: application/json
Content-Length: 36
{"name": "New item", "year": "2009"}
DATA
{"name": "New item", "year": "2009"}
RESPOND
HTTP/1.1 200 OK
Data saved successfully!
在我的纳米网络服务器中
和你一样 - 我很惊讶这个问题一次又一次地出现,但似乎没有明确的解决方案。
在此期间你有运气吗?我已经这么做了两天了,几乎要认输了。