This problem is very common. If you have worked with Rest API then things are pretty easy to understand.
Enable CORS:
I have created a rest API using python flask and it was hosted in Heroku. The advantage of Heroku was it support CORS by default and you do not need to set it up. Nowadays maximum server where you host your app especially python has the same facility. So those who have CORS related problem they have to first enable CROS it is mandatory.
Test In Postman:
It is required to test your API in Postman. If your app does not support CORS still it will work in Postman. So working in postman does not ensure that it will run in Unity.
The next important thing to consider is the Headers that you are using in the postman.
Like : {"Key":"Content-Type" , "value":"application/json" }
because you also need to pass it in unity www header.
The next thing needs to observe is what you are passing in the body and how you are passing it. Normally we send it as JSON(application/json) in Postman.
Like:
`{
"username":"Mukesh",
"password":"admin@1234",
"email_id":"mukeshh@gmail.com",
"us_dollar":"2000000000",
"device_id":"123456789"
}`
Now if your CORS enabled API is working fine in Postman then just relax it will also work in unity.
Unity Part :
First I have to create a class that will convert into Json.
[Serializable]
public class UserRegistration
{
//CAUTION:
//NOTE:
//DO NOT ALTER THE NAME OF PARAMETERS .
//THE JSON key WILL FAIL THEN .Properties will be the key of JSON .
/// <summary>
/// User name .
/// </summary>
public string username;
/// <summary>
/// Password .
/// </summary>
public string password;
/// <summary>
/// Emil id.
/// </summary>
public string email_id;
/// <summary>
/// JoeGames Doller .
/// </summary>
public string us_dollar;
/// <summary>
/// Device id .
/// </summary>
public string device_id;
/// <summary>
/// Constructor .
/// </summary>
/// <param name="username"></param>
/// <param name="password"></param>
/// <param name="email_id"></param>
/// <param name="us_dollar"></param>
/// <param name="device_id"></param>
public UserRegistration(string username, string password, string email_id, string us_dollar, string device_id)
{
this.username = username;
this.password = password;
this.email_id = email_id;
this.us_dollar = us_dollar;
this.device_id = device_id;
}
}
Next thing you have to convert the object in json.
//var create json.
var userregistration = new UserRegistration(
username: username,
password: password,
email_id: emailid,
us_dollar: joeGamesDollar.ToString(),
device_id: deviceid);
//convert to json.
var json = JsonUtility.ToJson(userregistration);
//debug.
Debug.Log("Print json"+json);
//update json.
json = json.Replace("'", "\"");
Next, convert json into the byte and make the post with the header.
//Encode the JSON string into a bytes
var postData = System.Text.Encoding.UTF8.GetBytes(json);
//create headers.
//Add keys an values .
var headers = new Dictionary<string, string> {{"Content-Type", "application/json"}};
//Now call a new WWW request
var www = new WWW(url,postData,headers);
//Yield return www .
yield return www;
Debug.Log("Error" + www.error.ToString());
Debug.Log("Data" + www.text);
Debug.Log(www.responseHeaders+"Done"+www.isDone);
//dispose.
www.Dispose();
Do not forget to write it in an Enumerator.
If you use something
like:
IEnumerator Upload()
{
WWWForm form = new WWWForm();
form.AddField("username", "Mukesh");
form.AddField("password", "admin@1234");
form.AddField("email_id", "mikesh@gmail.com");
form.AddField("us_dollar", "2000000");
form.AddField("device_id", device_id);
using (UnityWebRequest www = UnityWebRequest.Post(url, form))
{
yield return www.SendWebRequest();
if (www.isNetworkError || www.isHttpError)
{
Debug.Log(www.error);
}
else
{
Debug.Log("Form upload complete!");
}
}
}
You will get a Generic / Unknown Error because Unity Web Request can not make the post or send the data as your API required in this circumstance.
NOTE:
Some time 400 Bad request is also served as an unknown Generic/Unknown HTTP Error in unity. So do not forget to check the code in the backend to make sure your API is not getting any exception .