2015-05-23 119 views
2

當我使用CURL和瀏覽器執行登錄請求時,我的服務器行爲會有所不同。來自CURL和瀏覽器的不同服務器行爲

在做下面捲曲要求:

curl -i -X POST 'http://localhost:8080/login' -d 'username=fred&password=blah' -H 'content-type: application/x-www-form-urlencoded' 

我得到預期的結果的形式: response from curl request

然而,當做同樣的(或因此我認爲)從瀏覽器表單我請求請參見下面的結果在瀏覽器的調試器

canceled request canceled request details

用來做請求的形式的代碼如下

 <form action="localhost:8080/login" method="POST"> 
      <input type="text" name="username" placeholder="Username"> 
      <input type="text" name="password" placeholder="Password"> 
      <input type="submit" id="sign_in" value="Sign In"> 
     </form> 

我不認爲這是與請求的來源,因爲我設置Access-Controll-Allow-Origin': *一個問題。

服務器的整個代碼可以找到here。客戶端的代碼here

我沒有想法。什麼可能導致這個問題?

編輯:正如@GünterZöchbauer在下面的評論中所建議的,通常需要通過HttpRequest完成這種表單提交。我想用現成的解決方案添加答案,並直接解決另一個問題。 相關的HTML:

<form id="login_form" action="/login" method="POST" enctype="application/x-www-form-urlencoded"> 
    <input type="text" name="username" placeholder="Username"> 
    <input type="text" name="password" placeholder="Password"> 
    <input type="submit" id="sign_in" value="Sign In" on-click="{{submitLogin}}"> 
    </form> 

相關鏢代碼:

/* Login box */ 
    login_form = querySelector('#login_form'); 
    login_form.onSubmit.listen(submitLogin); 

/* Login code */ 
void submitLogin(Event e){ 
    e.preventDefault(); 

    FormElement form = e.target as FormElement; 
    print('inside of submitLogin'); 

    Uri loginUri = new Uri(scheme: 'http', 
     host: 'localhost', 
     port: 8080, 
     path: 'login'); 

    print(loginUri); 
    var request = new HttpRequest(); 
    request.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); 
    request.request(
     loginUri.toString(), 
     method: form.method, 
     sendData: new FormData(form) 
).then(onDataLoaded); 
} 

void onDataLoaded(HttpRequest req){ 
    String response = req.responseText; 
    print(response); 
    //TODO: do visual confiramtion of login 
} 

當comapring捲曲的從原來的要求(該工作)和一個由完成上面的代碼我注意到Content-Type是不同的。 我試圖以我知道的每種方式強制執行內容類型,但它一直保持不變。

curl "http://localhost:8080/login" -H "Origin: http://localhost:8080" -H "Accept-Encoding: gzip, deflate" -H "Accept-Language: pl-PL,pl;q=0.8,en-US;q=0.6,en;q=0.4" -H "User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.0 (Dart) Safari/537.36" -H "Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryZ1seZo8pq0PZt3Fg" -H "Accept: */*" -H "Referer: http://localhost:8080/" -H "Connection: keep-alive" --data-binary "------WebKitFormBoundaryZ1seZo8pq0PZt3Fg"^ 
"Content-Disposition: form-data; name=""username"""^ 

"fred"^ 
"------WebKitFormBoundaryZ1seZo8pq0PZt3Fg"^ 
"Content-Disposition: form-data; name=""password"""^ 

"blah"^ 
"------WebKitFormBoundaryZ1seZo8pq0PZt3Fg--"^ 
"" --compressed 

而不是。

curl "http://localhost:8080/login" -H "Origin: http://localhost:8080" -H "Accept-Encoding: gzip, deflate" -H "Accept-Language: pl-PL,pl;q=0.8,en-US;q=0.6,en;q=0.4" -H "User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.0 (Dart) Safari/537.36" -H "Content-Type: application/x-www-form-urlencoded" -H "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8" -H "Cache-Control: max-age=0" -H "Referer: http://localhost:8080/" -H "Connection: keep-alive" --data "username=fred&password=blah" --compressed 
+0

你得到一個錯誤信息?我從截圖中看不到一個。截圖應該告訴我什麼?如果你想支持CORS請求,我想你還需要允許請求類型'OPTIONS'和'POST'以及'Origin'。 –

+1

嘗試將操作更改爲「登錄」,「/ login」或「http:// localhost:8080/login」。 – Robert

+1

您可能希望做一個HttpRequest來代替發佈表單,因爲發佈表單會導致頁面重新加載,這通常不是您想要的單個頁面Dart應用程序中的內容。 –

回答

3

您在action屬性中的URL是相對的,這意味着它被附加到當前主機名。因此,如果您已在localhost:8080上,請將其更改爲絕對網址,方法是將http://或更改爲/login

1

此答案與問題的第二部分有關(請參閱編輯)。我無法在文檔中的任何位置找到現成的示例代碼。這就是爲什麼我添加下面的工作代碼作爲答案。如果你找到一種更優雅的方式從表格中獲取數據,請在這篇文章下面寫下評論。

HTML部分

<form id="login_form" action="/login" method="POST" enctype="application/x-www-form-urlencoded"> 
    <input type="text" name="username" placeholder="Username"> 
    <input type="text" name="password" placeholder="Password"> 
    <input type="submit" id="sign_in" value="Sign In"> 
    </form> 

鏢代碼 預訂事件

login_form = querySelector('#login_form'); 
login_form.onSubmit.listen(submitLogin); 

事件處理

/* Login code */ 
void submitLogin(Event e){ 
    e.preventDefault(); 

    FormElement form = e.target as FormElement; 
    print('inside of submitLogin'); 

    Uri loginUri = new Uri(scheme: 'http', 
     host: 'localhost', 
     port: 8080, 
     path: 'login'); 
    InputElement username = querySelector('[name="username"]'); 
    InputElement password = querySelector('[name="password"]'); 
    Map dataFromForm = {'username':username.value.toString(),'password':password.value.toString()}; 
    print(loginUri); 
    HttpRequest.postFormData(loginUri.toString(), dataFromForm) 
    .then(onDataLoaded); 
} 

void onDataLoaded(HttpRequest req){ 
    String response = req.responseText; 
    print(response); 
    //TODO: do visual 
+0

看起來不錯。也許你可以使用'form.querySelector()'來獲得輸入。 – Robert

相關問題